Skip to content

Commit

Permalink
fix (#1087): add app_dir option to docs serve/gen commands (#1088)
Browse files Browse the repository at this point in the history
* fix (#1087): add app_dir option to docs gen & serve commands

* lint: raise TypeError correctly

* lint: if TYPE_CHECKING imports
  • Loading branch information
Lancetnik authored Dec 23, 2023
1 parent ac6d0ed commit 1e5f52e
Show file tree
Hide file tree
Showing 11 changed files with 67 additions and 43 deletions.
7 changes: 4 additions & 3 deletions faststream/asyncapi/generate.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Any, Dict, List, Union
from typing import TYPE_CHECKING, Any, Dict, List, Union

from faststream._compat import HAS_FASTAPI, PYDANTIC_V2
from faststream.app import FastStream
Expand All @@ -13,8 +13,9 @@
)
from faststream.constants import ContentTypes

if HAS_FASTAPI:
from faststream.broker.fastapi.router import StreamRouter
if TYPE_CHECKING:
if HAS_FASTAPI:
from faststream.broker.fastapi.router import StreamRouter


def get_app_schema(app: Union[FastStream, "StreamRouter[Any]"]) -> Schema:
Expand Down
15 changes: 6 additions & 9 deletions faststream/broker/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,21 +275,18 @@ async def consume(self, msg: MsgType) -> SendableMessage: # type: ignore[overri
async with AsyncExitStack() as stack:
stack.enter_context(self.lock)

gl_middlewares: List[BaseMiddleware] = []

stack.enter_context(context.scope("handler_", self))

for m in self.global_middlewares:
gl_middlewares.append(await stack.enter_async_context(m(msg)))
gl_middlewares: List[BaseMiddleware] = [
await stack.enter_async_context(m(msg)) for m in self.global_middlewares
]

logged = False
processed = False
for handler, filter_, parser, decoder, middlewares, _ in self.calls:
local_middlewares: List[BaseMiddleware] = []
for local_m in middlewares:
local_middlewares.append(
await stack.enter_async_context(local_m(msg))
)
local_middlewares: List[BaseMiddleware] = [
await stack.enter_async_context(m(msg)) for m in middlewares
]

all_middlewares = gl_middlewares + local_middlewares

Expand Down
23 changes: 23 additions & 0 deletions faststream/cli/docs/app.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import json
import sys
import warnings
from pathlib import Path
from typing import Optional, Sequence
Expand Down Expand Up @@ -35,9 +36,20 @@ def serve(
is_flag=True,
help="Restart documentation at directory files changes",
),
app_dir: str = typer.Option(
".",
"--app-dir",
help=(
"Look for APP in the specified directory, by adding this to the PYTHONPATH."
" Defaults to the current working directory."
),
),
) -> None:
"""Serve project AsyncAPI schema."""
if ":" in app:
if app_dir: # pragma: no branch
sys.path.insert(0, app_dir)

module, _ = import_from_string(app)

module_parent = module.parent
Expand Down Expand Up @@ -84,8 +96,19 @@ def gen(
None,
help="output filename",
),
app_dir: str = typer.Option(
".",
"--app-dir",
help=(
"Look for APP in the specified directory, by adding this to the PYTHONPATH."
" Defaults to the current working directory."
),
),
) -> None:
"""Generate project AsyncAPI schema."""
if app_dir: # pragma: no branch
sys.path.insert(0, app_dir)

_, app_obj = import_from_string(app)
raw_schema = get_app_schema(app_obj)

Expand Down
8 changes: 5 additions & 3 deletions faststream/cli/supervisors/multiprocess.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
from multiprocessing.context import SpawnProcess
from typing import Any, List, Tuple
from typing import TYPE_CHECKING, Any, List, Tuple

from faststream.cli.supervisors.basereload import BaseReload
from faststream.log import logger
from faststream.types import DecoratedCallable

if TYPE_CHECKING:
from multiprocessing.context import SpawnProcess


class Multiprocess(BaseReload):
"""A class to represent a multiprocess.
Expand Down Expand Up @@ -40,7 +42,7 @@ def __init__(
super().__init__(target, args, None)

self.workers = workers
self.processes: List[SpawnProcess] = []
self.processes: List["SpawnProcess"] = []

def startup(self) -> None:
logger.info(f"Started parent process [{self.pid}]")
Expand Down
2 changes: 1 addition & 1 deletion faststream/cli/utils/imports.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def get_app_path(app: str) -> Tuple[Path, str]:
"""
if ":" not in app:
raise ValueError(f"{app} is not a FastStream")
raise ValueError(f"`{app}` is not a FastStream")

module, app_name = app.split(":", 2)

Expand Down
2 changes: 1 addition & 1 deletion faststream/kafka/publisher.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ async def publish( # type: ignore[override]
to_send: Sequence[SendableMessage]
if not messages:
if not isinstance(message, Sequence):
raise ValueError(
raise TypeError(
f"Message: {message} should be Sequence type to send in batch"
)
else:
Expand Down
4 changes: 1 addition & 3 deletions faststream/redis/broker.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,7 @@ def subscriber( # type: ignore[override]
stream = StreamSub.validate(stream)

if (any_of := channel or list or stream) is None:
raise ValueError(
"You should specify `channel`, `list`, `stream` subscriber type"
)
raise ValueError(INCORRECT_SETUP_MSG)

if all((channel, list)):
raise ValueError("You can't use `PubSub` and `ListSub` both")
Expand Down
4 changes: 2 additions & 2 deletions faststream/redis/message.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
from typing import TYPE_CHECKING, Any, List, Literal, Optional, TypeVar, Union

from redis.asyncio import Redis

from faststream._compat import NotRequired, TypedDict, override
from faststream.broker.message import StreamMessage
from faststream.utils.context.repository import context

if TYPE_CHECKING:
from redis.asyncio import Redis

from faststream.redis.asyncapi import Handler


Expand Down
9 changes: 5 additions & 4 deletions faststream/redis/producer.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
from typing import Any, Optional, Union, overload
from typing import TYPE_CHECKING, Any, Optional, Union, overload
from uuid import uuid4

from redis.asyncio.client import PubSub, Redis

from faststream.broker.parsers import encode_message, resolve_custom_func
from faststream.broker.types import (
AsyncCustomDecoder,
Expand All @@ -23,6 +21,9 @@
from faststream.types import AnyDict, DecodedMessage, SendableMessage
from faststream.utils.functions import timeout_scope

if TYPE_CHECKING:
from redis.asyncio.client import PubSub, Redis


class RedisFastProducer:
"""A class to represent a Redis producer."""
Expand Down Expand Up @@ -94,7 +95,7 @@ async def publish(
if not any((channel, list, stream)):
raise ValueError(INCORRECT_SETUP_MSG)

psub: Optional[PubSub] = None
psub: Optional["PubSub"] = None
if rpc is True:
if reply_to:
raise WRONG_PUBLISH_ARGS
Expand Down
34 changes: 18 additions & 16 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -183,22 +183,24 @@ exclude = ["docs/docs_src"]

[tool.ruff.lint]
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"C90", # mccabe
"N", # pep8-naming
"D", # pydocstyle
"F", # pyflakes
"I", # isort
"ASYNC", # flake8-async
"C", # flake8-comprehensions
"B", # flake8-bugbear
"Q", # flake8-quotes
"T20", # flake8-print
"SIM", # flake8-simplify
"PT", # flake8-pytest-style
"PTH", # flake8-use-pathlib
"RUF", # Ruff-specific rules
"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
"RUF", # Ruff-specific rules https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf
"PERF", # Perflint https://docs.astral.sh/ruff/rules/#perflint-perf
]

ignore = [
Expand Down
2 changes: 1 addition & 1 deletion tests/cli/utils/test_imports.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def test_get_app_path(test_input, exp_module, exp_app):


def test_get_app_path_wrong():
with pytest.raises(ValueError): # noqa: PT011
with pytest.raises(ValueError, match="`module.app` is not a FastStream"):
get_app_path("module.app")


Expand Down

0 comments on commit 1e5f52e

Please sign in to comment.