from typing import TYPE_CHECKING, Any, Callable, Dict, Optional, Pattern, TypeVar, Union from typing_extensions import Annotated from ninja.params import functions as param_functions __all__ = [ "Body", "Cookie", "File", "Form", "Header", "Path", "Query", "BodyEx", "CookieEx", "FileEx", "FormEx", "HeaderEx", "PathEx", "QueryEx", "P", ] class ParamShortcut: def __init__(self, base_func: Callable[..., Any]) -> None: self._base_func = base_func def __call__(self, *args: Any, **kwargs: Any) -> Any: return self._base_func(*args, **kwargs) def __getitem__(self, args: Any) -> Any: if isinstance(args, tuple): return Annotated[args[0], self._base_func(**args[1])] return Annotated[args, self._base_func()] if TYPE_CHECKING: # pragma: nocover # mypy cheats T = TypeVar("T") Body = Annotated[T, param_functions.Body()] Cookie = Annotated[T, param_functions.Cookie()] File = Annotated[T, param_functions.File()] Form = Annotated[T, param_functions.Form()] Header = Annotated[T, param_functions.Header()] Path = Annotated[T, param_functions.Path()] Query = Annotated[T, param_functions.Query()] # mypy does not like to extend already annotated params # with extra annotation (so need to cheat with these XXX-Ex types): from typing_extensions import Annotated as BodyEx from typing_extensions import Annotated as CookieEx from typing_extensions import Annotated as FileEx from typing_extensions import Annotated as FormEx from typing_extensions import Annotated as HeaderEx from typing_extensions import Annotated as PathEx from typing_extensions import Annotated as QueryEx else: Body = ParamShortcut(param_functions.Body) Cookie = ParamShortcut(param_functions.Cookie) File = ParamShortcut(param_functions.File) Form = ParamShortcut(param_functions.Form) Header = ParamShortcut(param_functions.Header) Path = ParamShortcut(param_functions.Path) Query = ParamShortcut(param_functions.Query) # mypy does not like to extend already annotated params # with extra annotation (so need to cheat with these XXX-Ex types): BodyEx = Body CookieEx = Cookie FileEx = File FormEx = Form HeaderEx = Header PathEx = Path QueryEx = Query def P( *, alias: Optional[str] = None, title: Optional[str] = None, description: Optional[str] = None, gt: Optional[float] = None, ge: Optional[float] = None, lt: Optional[float] = None, le: Optional[float] = None, min_length: Optional[int] = None, max_length: Optional[int] = None, pattern: Union[str, Pattern[str], None] = None, example: Any = None, examples: Optional[Dict[str, Any]] = None, deprecated: Optional[bool] = None, include_in_schema: bool = True, **extra: Any, ) -> Dict[str, Any]: "Arguments for BodyEx, QueryEx, etc." return dict( alias=alias, title=title, description=description, gt=gt, ge=ge, lt=lt, le=le, min_length=min_length, max_length=max_length, pattern=pattern, example=example, examples=examples, deprecated=deprecated, include_in_schema=include_in_schema, **extra, )