From 27ab0b59933da31e993aa56f670e29935802fe5e Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Thu, 12 Sep 2024 19:34:13 +0300 Subject: [PATCH] lint: fix mypy --- faststream/_internal/application.py | 23 ++++-- faststream/app.py | 1 + faststream/asgi/app.py | 23 ++++-- faststream/cli/main.py | 16 ++--- faststream/cli/utils/imports.py | 104 ++++++++++++++-------------- faststream/cli/utils/logs.py | 4 +- 6 files changed, 95 insertions(+), 76 deletions(-) diff --git a/faststream/_internal/application.py b/faststream/_internal/application.py index 0e8c61e320..dd0140db4d 100644 --- a/faststream/_internal/application.py +++ b/faststream/_internal/application.py @@ -76,13 +76,23 @@ def __init__( self.logger = logger self.context = context - self._on_startup_calling: List[AsyncFunc] = [apply_types(to_async(x)) for x in on_startup] - self._after_startup_calling: List[AsyncFunc] = [apply_types(to_async(x)) for x in after_startup] - self._on_shutdown_calling: List[AsyncFunc] = [apply_types(to_async(x)) for x in on_shutdown] - self._after_shutdown_calling: List[AsyncFunc] = [apply_types(to_async(x)) for x in after_shutdown] + self._on_startup_calling: List[AsyncFunc] = [ + apply_types(to_async(x)) for x in on_startup + ] + self._after_startup_calling: List[AsyncFunc] = [ + apply_types(to_async(x)) for x in after_startup + ] + self._on_shutdown_calling: List[AsyncFunc] = [ + apply_types(to_async(x)) for x in on_shutdown + ] + self._after_shutdown_calling: List[AsyncFunc] = [ + apply_types(to_async(x)) for x in after_shutdown + ] if lifespan is not None: - self.lifespan_context = apply_types(func=lifespan, wrap_model=drop_response_type) + self.lifespan_context = apply_types( + func=lifespan, wrap_model=drop_response_type + ) else: self.lifespan_context = fake_context @@ -103,8 +113,7 @@ async def run( log_level: int, run_extra_options: Optional[Dict[str, "SettingField"]] = None, sleep_time: float = 0.1, - ) -> None: - ... + ) -> None: ... def set_broker(self, broker: "BrokerUsecase[Any, Any]") -> None: """Set already existed App object broker. diff --git a/faststream/app.py b/faststream/app.py index 1ef267be7d..3f6c2d546f 100644 --- a/faststream/app.py +++ b/faststream/app.py @@ -68,6 +68,7 @@ def as_asgi( ) -> AsgiFastStream: return AsgiFastStream.from_app(self, asgi_routes, asyncapi_path) + try: from contextlib import asynccontextmanager diff --git a/faststream/asgi/app.py b/faststream/asgi/app.py index 6f5a534f76..0e82f4443b 100644 --- a/faststream/asgi/app.py +++ b/faststream/asgi/app.py @@ -9,6 +9,7 @@ Sequence, Tuple, Union, + cast, ) import anyio @@ -94,10 +95,10 @@ def __init__( @classmethod def from_app( - cls, - app: Application, - asgi_routes: Sequence[Tuple[str, "ASGIApp"]], - asyncapi_path: Optional[str] = None + cls, + app: Application, + asgi_routes: Sequence[Tuple[str, "ASGIApp"]], + asyncapi_path: Optional[str] = None, ) -> "AsgiFastStream": asgi_app = cls( app.broker, @@ -143,12 +144,20 @@ async def run( self, log_level: int, run_extra_options: Optional[Dict[str, "SettingField"]] = None, - sleep_time: float = 0.1 + sleep_time: float = 0.1, ) -> None: import uvicorn - port = run_extra_options.pop("port", 1337) + + run_extra_options = run_extra_options or {} + port = cast(str, run_extra_options.pop("port", "1337")) host = run_extra_options.pop("host", "0.0.0.0") - config = uvicorn.Config(self, host=host, port=int(port), log_level=log_level, **run_extra_options) + config = uvicorn.Config( + self, + host=host, + port=int(port), + log_level=log_level, + **run_extra_options, + ) server = uvicorn.Server(config) await server.serve() diff --git a/faststream/cli/main.py b/faststream/cli/main.py index e2b53e4b88..1bf04eb130 100644 --- a/faststream/cli/main.py +++ b/faststream/cli/main.py @@ -117,9 +117,6 @@ def run( args = (app, extra, is_factory, casted_log_level) - if not isinstance(app_obj, FastStream): - return app_obj.run() # TODO: explicit uvicorn run call - if reload and workers > 1: raise SetupError("You can't use reload option with multiprocessing") @@ -146,11 +143,14 @@ def run( elif workers > 1: from faststream.cli.supervisors.multiprocess import Multiprocess - return Multiprocess( - target=_run, - args=(*args, logging.DEBUG), - workers=workers, - ).run() + if isinstance(app_obj, FastStream): + return Multiprocess( + target=_run, + args=(*args, logging.DEBUG), + workers=workers, + ).run() + else: + return _run(*args) else: return _run(*args) diff --git a/faststream/cli/utils/imports.py b/faststream/cli/utils/imports.py index 3f2205a56e..230c5d718d 100644 --- a/faststream/cli/utils/imports.py +++ b/faststream/cli/utils/imports.py @@ -11,10 +11,58 @@ from faststream._internal.application import Application -def try_import_app(module: Path, app: str) -> "Application": +def import_from_string( + import_str: str, + *, + is_factory: bool = False, +) -> Tuple[Path, "Application"]: + """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") + + module_str, _, attrs_str = import_str.partition(":") + if not module_str or not attrs_str: + raise typer.BadParameter( + f'Import string "{import_str}" must be in format ":"' + ) + + try: + module = importlib.import_module( # nosemgrep: python.lang.security.audit.non-literal-import.non-literal-import + module_str + ) + + except ModuleNotFoundError: + module_path, app_name = _get_app_path(import_str) + instance = _try_import_app(module_path, app_name) + + else: + attr = module + try: + for attr_str in attrs_str.split("."): + attr = getattr(attr, attr_str) + instance = attr # type: ignore[assignment] + + except AttributeError as e: + typer.echo(e, err=True) + raise typer.BadParameter( + f'Attribute "{attrs_str}" not found in module "{module_str}".' + ) from e + + if module.__file__: + module_path = Path(module.__file__).resolve().parent + else: + module_path = Path.cwd() + + if is_factory: + instance = instance() # type: ignore[operator] + + return module_path, instance + + +def _try_import_app(module: Path, app: str) -> "Application": """Tries to import a FastStream app from a module.""" try: - app_object = import_object(module, app) + app_object = _import_object(module, app) except FileNotFoundError as e: typer.echo(e, err=True) @@ -26,7 +74,7 @@ def try_import_app(module: Path, app: str) -> "Application": return app_object # type: ignore -def import_object(module: Path, app: str) -> object: +def _import_object(module: Path, app: str) -> object: """Import an object from a module.""" spec = spec_from_file_location( "mode", @@ -53,7 +101,7 @@ def import_object(module: Path, app: str) -> object: return obj -def get_app_path(app: str) -> Tuple[Path, str]: +def _get_app_path(app: str) -> Tuple[Path, str]: """Get the application path.""" if ":" not in app: raise SetupError(f"`{app}` is not a FastStream") @@ -65,51 +113,3 @@ def get_app_path(app: str) -> Tuple[Path, str]: mod_path = mod_path / i return mod_path, app_name - - -def import_from_string( - import_str: str, - *, - is_factory: bool = False, -) -> Tuple[Path, "Application"]: - """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") - - module_str, _, attrs_str = import_str.partition(":") - if not module_str or not attrs_str: - raise typer.BadParameter( - f'Import string "{import_str}" must be in format ":"' - ) - - try: - module = importlib.import_module( # nosemgrep: python.lang.security.audit.non-literal-import.non-literal-import - module_str - ) - - except ModuleNotFoundError: - module_path, app_name = get_app_path(import_str) - instance = try_import_app(module_path, app_name) - - else: - attr = module - try: - for attr_str in attrs_str.split("."): - attr = getattr(attr, attr_str) - instance = attr # type: ignore[assignment] - - except AttributeError as e: - typer.echo(e, err=True) - raise typer.BadParameter( - f'Attribute "{attrs_str}" not found in module "{module_str}".' - ) from e - - if module.__file__: - module_path = Path(module.__file__).resolve().parent - else: - module_path = Path.cwd() - - if is_factory: - instance = instance() - - return module_path, instance diff --git a/faststream/cli/utils/logs.py b/faststream/cli/utils/logs.py index b576db49ee..c695b2e5be 100644 --- a/faststream/cli/utils/logs.py +++ b/faststream/cli/utils/logs.py @@ -4,7 +4,7 @@ from typing import TYPE_CHECKING, DefaultDict, Optional, Union if TYPE_CHECKING: - from faststream.app import FastStream + from faststream._internal.application import Application from faststream.types import LoggerProto @@ -64,7 +64,7 @@ def get_log_level(level: Union[LogLevels, str, int]) -> int: return LOG_LEVELS[level.lower()] -def set_log_level(level: int, app: "FastStream") -> None: +def set_log_level(level: int, app: "Application") -> None: """Sets the log level for an application.""" if app.logger and getattr(app.logger, "setLevel", None): app.logger.setLevel(level) # type: ignore[attr-defined]