diff --git a/pyproject.toml b/pyproject.toml index a67b900..acfb9eb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ license = "MIT" license-files = ["LICENSE"] requires-python = ">=3.10" -version = "1.2.0" +version = "1.2.1" keywords = [ "rabbitmq", diff --git a/src/faststream_fastapi/_internal/get_dependant.py b/src/faststream_fastapi/_internal/get_dependant.py index b44771f..22499dd 100644 --- a/src/faststream_fastapi/_internal/get_dependant.py +++ b/src/faststream_fastapi/_internal/get_dependant.py @@ -1,7 +1,9 @@ import inspect from collections.abc import Callable, Iterable +from dataclasses import dataclass, fields from typing import Annotated, Any, Final, cast, get_args, get_origin +from fast_depends.library.serializer import OptionItem from fast_depends.utils import get_typed_annotation from fastapi.dependencies.models import Dependant from fastapi.dependencies.utils import ( @@ -10,15 +12,22 @@ get_typed_signature, ) from fastapi.params import Depends -from pydantic import Field +from pydantic import Field, create_model from faststream_fastapi._internal.fs_re_exports._compat import PYDANTIC_V2, PydanticUndefined +@dataclass(slots=True, kw_only=True) +class FastStreamDependant(Dependant): + model: type[Any] + custom_fields: dict[str, Any] + flat_params: list[OptionItem] + + def get_fastapi_dependant( orig_call: Callable[..., Any], dependencies: Iterable[Depends], -) -> Dependant: +) -> FastStreamDependant: dependent = get_fastapi_native_dependant(orig_call=orig_call, dependencies=dependencies) return _patch_fastapi_dependent(dependent) @@ -41,7 +50,7 @@ def get_fastapi_native_dependant( return dependent -def _patch_fastapi_dependent(dependant: Dependant) -> Dependant: +def _patch_fastapi_dependent(dependant: Dependant) -> FastStreamDependant: params = dependant.query_params + dependant.body_params for d in dependant.dependencies: @@ -117,7 +126,17 @@ def _patch_fastapi_dependent(dependant: Dependant) -> Dependant: f, ) - return dependant + return FastStreamDependant( + model=create_model(getattr(call, "__name__", type(call).__name__)), + custom_fields={}, + flat_params=[ + OptionItem(field_name=name, field_type=type_, default_value=default) + for name, (type_, default) in params_unique.items() + ], + **{ + field.name: getattr(dependant, field.name) for field in fields(dependant) if field.init + }, + ) def has_forbidden_types( # noqa: C901 diff --git a/tests/test_patched_dependant.py b/tests/test_patched_dependant.py new file mode 100644 index 0000000..67a3454 --- /dev/null +++ b/tests/test_patched_dependant.py @@ -0,0 +1,25 @@ +from typing import Annotated + +from fastapi import Depends + +from faststream_fastapi._internal.get_dependant import get_fastapi_dependant + + +def test_pathed_dependant() -> None: + async def dependency() -> str: + return "dependency" + + async def handler( + message: str, + dependency_value: Annotated[str, Depends(dependency)], + ) -> None: + return None + + dependant = get_fastapi_dependant(handler, ()) + + assert dependant.call is handler + assert len(dependant.dependencies) == 1 + assert dependant.dependencies[0].call is dependency + assert dependant.model.__name__ == "handler" + assert dependant.custom_fields == {} + assert [field.field_name for field in dependant.flat_params] == ["message"] diff --git a/uv.lock b/uv.lock index 0da7bd4..b942a35 100644 --- a/uv.lock +++ b/uv.lock @@ -789,7 +789,7 @@ redis = [ [[package]] name = "faststream-fastapi" -version = "1.2.0" +version = "1.2.1" source = { editable = "." } dependencies = [ { name = "fastapi" },