From b04040f15240703894ec35897060552a1ac080e4 Mon Sep 17 00:00:00 2001 From: Lancetnik Date: Thu, 1 Jun 2023 21:12:51 +0300 Subject: [PATCH 01/18] create command --- .gitignore | 3 +- asyncapi_docs/kafka_full.yaml | 149 ++++++++++++++++++++++++++++++++++ asyncapi_docs/title_min.yaml | 24 ++++++ propan/__about__.py | 2 +- propan/asyncapi/__init__.py | 3 + propan/asyncapi/main.py | 1 + propan/cli/docs/__init__.py | 3 + propan/cli/docs/app.py | 23 ++++++ propan/cli/docs/gen.py | 7 ++ propan/cli/main.py | 38 ++++----- propan/cli/utils/imports.py | 20 +++++ pyproject.toml | 9 +- 12 files changed, 254 insertions(+), 28 deletions(-) create mode 100644 asyncapi_docs/kafka_full.yaml create mode 100644 asyncapi_docs/title_min.yaml create mode 100644 propan/asyncapi/__init__.py create mode 100644 propan/asyncapi/main.py create mode 100644 propan/cli/docs/__init__.py create mode 100644 propan/cli/docs/app.py create mode 100644 propan/cli/docs/gen.py diff --git a/.gitignore b/.gitignore index 653bdb95..12486d67 100644 --- a/.gitignore +++ b/.gitignore @@ -17,4 +17,5 @@ wtf .mypy_cache coverage.json site -Dockerfile \ No newline at end of file +Dockerfile +t \ No newline at end of file diff --git a/asyncapi_docs/kafka_full.yaml b/asyncapi_docs/kafka_full.yaml new file mode 100644 index 00000000..2755c451 --- /dev/null +++ b/asyncapi_docs/kafka_full.yaml @@ -0,0 +1,149 @@ +asyncapi: '2.6.0' +info: + title: Streetlights Kafka API + version: '1.0.0' + description: | + The Smartylighting Streetlights API allows you to remotely manage the city lights. + ### Check out its awesome features: + * Turn a specific streetlight on/off πŸŒƒ + * Dim a specific streetlight 😎 + * Receive real-time information about environmental lighting conditions πŸ“ˆ + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0 +servers: + test: + url: test.mykafkacluster.org:8092 + protocol: kafka-secure + description: Test broker + security: + - saslScram: [] +defaultContentType: application/json +channels: + smartylighting.streetlights.1.0.event.{streetlightId}.lighting.measured: + description: The topic on which measured values may be produced and consumed. + parameters: + streetlightId: + $ref: '#/components/parameters/streetlightId' + publish: + summary: Inform about environmental lighting conditions of a particular streetlight. + operationId: receiveLightMeasurement + traits: + - $ref: '#/components/operationTraits/kafka' + message: + $ref: '#/components/messages/lightMeasured' + smartylighting.streetlights.1.0.action.{streetlightId}.turn.on: + parameters: + streetlightId: + $ref: '#/components/parameters/streetlightId' + subscribe: + operationId: turnOn + traits: + - $ref: '#/components/operationTraits/kafka' + message: + $ref: '#/components/messages/turnOnOff' + smartylighting.streetlights.1.0.action.{streetlightId}.turn.off: + parameters: + streetlightId: + $ref: '#/components/parameters/streetlightId' + subscribe: + operationId: turnOff + traits: + - $ref: '#/components/operationTraits/kafka' + message: + $ref: '#/components/messages/turnOnOff' + smartylighting.streetlights.1.0.action.{streetlightId}.dim: + parameters: + streetlightId: + $ref: '#/components/parameters/streetlightId' + subscribe: + operationId: dimLight + traits: + - $ref: '#/components/operationTraits/kafka' + message: + $ref: '#/components/messages/dimLight' +components: + messages: + lightMeasured: + name: lightMeasured + title: Light measured + summary: Inform about environmental lighting conditions of a particular streetlight. + contentType: application/json + traits: + - $ref: '#/components/messageTraits/commonHeaders' + payload: + $ref: "#/components/schemas/lightMeasuredPayload" + turnOnOff: + name: turnOnOff + title: Turn on/off + summary: Command a particular streetlight to turn the lights on or off. + traits: + - $ref: '#/components/messageTraits/commonHeaders' + payload: + $ref: "#/components/schemas/turnOnOffPayload" + dimLight: + name: dimLight + title: Dim light + summary: Command a particular streetlight to dim the lights. + traits: + - $ref: '#/components/messageTraits/commonHeaders' + payload: + $ref: "#/components/schemas/dimLightPayload" + schemas: + lightMeasuredPayload: + type: object + properties: + lumens: + type: integer + minimum: 0 + description: Light intensity measured in lumens. + sentAt: + $ref: "#/components/schemas/sentAt" + turnOnOffPayload: + type: object + properties: + command: + type: string + enum: + - on + - off + description: Whether to turn on or off the light. + sentAt: + $ref: "#/components/schemas/sentAt" + dimLightPayload: + type: object + properties: + percentage: + type: integer + description: Percentage to which the light should be dimmed to. + minimum: 0 + maximum: 100 + sentAt: + $ref: "#/components/schemas/sentAt" + sentAt: + type: string + format: date-time + description: Date and time when the message was sent. + securitySchemes: + saslScram: + type: scramSha256 + description: Provide your username and password for SASL/SCRAM authentication + parameters: + streetlightId: + description: The ID of the streetlight. + schema: + type: string + messageTraits: + commonHeaders: + headers: + type: object + properties: + my-app-header: + type: integer + minimum: 0 + maximum: 100 + operationTraits: + kafka: + bindings: + kafka: + clientId: my-app-id diff --git a/asyncapi_docs/title_min.yaml b/asyncapi_docs/title_min.yaml new file mode 100644 index 00000000..62eac130 --- /dev/null +++ b/asyncapi_docs/title_min.yaml @@ -0,0 +1,24 @@ +asyncapi: '2.6.0' + +info: + title: Streetlights Kafka API + version: '1.0.0' + description: | + The Smartylighting Streetlights API allows you to remotely manage the city lights. + ### Check out its awesome features: + * Turn a specific streetlight on/off πŸŒƒ + * Dim a specific streetlight 😎 + * Receive real-time information about environmental lighting conditions πŸ“ˆ + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0 + +servers: + test: + url: test.mykafkacluster.org:8092 + protocol: kafka-secure + description: Test broker + security: + - saslScram: [] + +defaultContentType: application/json \ No newline at end of file diff --git a/propan/__about__.py b/propan/__about__.py index c9501676..34288307 100644 --- a/propan/__about__.py +++ b/propan/__about__.py @@ -1,6 +1,6 @@ """Simple and fast framework to create message brokers based microservices""" -__version__ = "0.1.2.0" +__version__ = "0.1.2.8" INSTALL_MESSAGE = ( diff --git a/propan/asyncapi/__init__.py b/propan/asyncapi/__init__.py new file mode 100644 index 00000000..b4cf27dc --- /dev/null +++ b/propan/asyncapi/__init__.py @@ -0,0 +1,3 @@ +from propan.asyncapi.main import ASYNC_API_VERSION + +__all__ = ("ASYNC_API_VERSION",) diff --git a/propan/asyncapi/main.py b/propan/asyncapi/main.py new file mode 100644 index 00000000..2ed07563 --- /dev/null +++ b/propan/asyncapi/main.py @@ -0,0 +1 @@ +ASYNC_API_VERSION = "2.6.0" diff --git a/propan/cli/docs/__init__.py b/propan/cli/docs/__init__.py new file mode 100644 index 00000000..e179343d --- /dev/null +++ b/propan/cli/docs/__init__.py @@ -0,0 +1,3 @@ +from propan.cli.docs.app import docs_app + +__all__ = ("docs_app",) diff --git a/propan/cli/docs/app.py b/propan/cli/docs/app.py new file mode 100644 index 00000000..de241ada --- /dev/null +++ b/propan/cli/docs/app.py @@ -0,0 +1,23 @@ +import sys + +import typer + +from propan.cli.docs.gen import generate_doc_file +from propan.cli.utils.imports import get_app_path, try_import_propan + +docs_app = typer.Typer(pretty_exceptions_short=True) + + +@docs_app.command(name="gen") +def gen( + app: str = typer.Argument( + ..., help="[python_module:PropanApp] - path to your application" + ), +) -> None: + """Generate an AsyncAPI schema.yaml for your project""" + module, app = get_app_path(app) + app_dir = module.parent + sys.path.insert(0, str(app_dir)) + propan_app = try_import_propan(module, app) + + generate_doc_file(propan_app) diff --git a/propan/cli/docs/gen.py b/propan/cli/docs/gen.py new file mode 100644 index 00000000..5772bfdc --- /dev/null +++ b/propan/cli/docs/gen.py @@ -0,0 +1,7 @@ +import typer + +from propan.cli.app import PropanApp + + +def generate_doc_file(app: PropanApp) -> None: + typer.echo(app) diff --git a/propan/cli/main.py b/propan/cli/main.py index c1b0b88b..2c6d9762 100644 --- a/propan/cli/main.py +++ b/propan/cli/main.py @@ -7,9 +7,9 @@ import typer from propan.__about__ import __version__ -from propan.cli.app import PropanApp +from propan.cli.docs import docs_app from propan.cli.startproject import create_app -from propan.cli.utils.imports import get_app_path, import_object +from propan.cli.utils.imports import get_app_path, try_import_propan from propan.cli.utils.logs import LogLevels, get_log_level, set_log_level from propan.cli.utils.parser import SettingField, parse_cli_args from propan.log import logger @@ -18,6 +18,7 @@ cli.add_typer( create_app, name="create", help="Create a new Propan project at [APPNAME] directory" ) +cli.add_typer(docs_app, name="docs", help="AsyncAPI schema commands") def version_callback(version: bool) -> None: @@ -106,28 +107,17 @@ def _run( log_level: int = logging.INFO, app_level: int = logging.INFO, ) -> None: - try: - propan_app = import_object(module, app) + propan_app = try_import_propan(module, app) + set_log_level(log_level, propan_app) - if not isinstance(propan_app, PropanApp): - raise ValueError(f"{propan_app} is not a PropanApp") + propan_app._command_line_options = extra_options - except (ValueError, FileNotFoundError, AttributeError) as e: - logger.error(e) - logger.error("Please, input module like [python_file:propan_app_name]") - exit() + if sys.platform not in ("win32", "cygwin", "cli"): + try: + import uvloop + except Exception: + logger.warning("You have no installed `uvloop`") + else: + uvloop.install() - else: - set_log_level(log_level, propan_app) - - propan_app._command_line_options = extra_options - - if sys.platform not in ("win32", "cygwin", "cli"): - try: - import uvloop - except Exception: - logger.warning("You have no installed `uvloop`") - else: - uvloop.install() - - asyncio.run(propan_app.run(log_level=app_level)) + asyncio.run(propan_app.run(log_level=app_level)) diff --git a/propan/cli/utils/imports.py b/propan/cli/utils/imports.py index 2d0f7b64..3724ab6b 100644 --- a/propan/cli/utils/imports.py +++ b/propan/cli/utils/imports.py @@ -2,6 +2,26 @@ from pathlib import Path from typing import Any, Tuple +import typer + +from propan.cli.app import PropanApp + + +def try_import_propan(module: Path, app: str) -> PropanApp: + try: + propan_app = import_object(module, app) + + if not isinstance(propan_app, PropanApp): + raise ValueError(f"{propan_app} is not a PropanApp") + + except (ValueError, FileNotFoundError, AttributeError) as e: + typer.echo(e, err=True) + typer.echo("Please, input module like [python_file:propan_app_name]", err=True) + raise typer.Exit() from e + + else: + return propan_app + def import_object(module: Path, app: str) -> Any: spec = spec_from_file_location("mode", f"{module}.py") diff --git a/pyproject.toml b/pyproject.toml index df3ee035..c11733d2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -79,11 +79,16 @@ async-kafka = [ "aiokafka>=0.8" ] +doc = [ + "PyYAML", +] + test = [ "propan[async-rabbit]", "propan[async-nats]", "propan[async-redis]", "propan[async-kafka]", + "propan[doc]", "coverage[toml]>=7.2", "pytest>=7", @@ -95,7 +100,7 @@ test = [ "asyncmock; python_version < '3.8'", ] -doc = [ +dev-doc = [ "mkdocs-material >=8.1.4,<9.0.0", "mkdocs-static-i18n", "mdx-include >=1.4.1,<2.0.0", @@ -106,7 +111,7 @@ doc = [ dev = [ "propan[test]", - "propan[doc]", + "propan[dev-doc]", "types-redis", From 3edb783cd795b4dce859db25849020ff3f32638b Mon Sep 17 00:00:00 2001 From: Lancetnik Date: Thu, 1 Jun 2023 21:38:21 +0300 Subject: [PATCH 02/18] generate project info --- asyncapi.yaml | 6 ++++ docs/docs_src/contributing/adapter/parent.py | 4 +-- .../contributing/adapter/rabbit_connect.py | 2 +- .../contributing/adapter/rabbit_handle.py | 4 +-- .../contributing/adapter/rabbit_init.py | 2 +- .../contributing/adapter/rabbit_parse.py | 4 +-- .../contributing/adapter/rabbit_process.py | 4 +-- .../contributing/adapter/redis_process.py | 4 +-- .../contributing/adapter/redis_publish.py | 2 +- .../contributing/adapter/redis_start.py | 2 +- propan/asyncapi/__init__.py | 6 +++- propan/asyncapi/info.py | 7 +++++ propan/brokers/_model/__init__.py | 4 +++ .../{model => _model}/broker_usecase.py | 4 +-- propan/brokers/{model => _model}/schemas.py | 0 propan/brokers/{model => _model}/utils.py | 0 propan/brokers/kafka/kafka_broker.py | 4 +-- propan/brokers/kafka/kafka_broker.pyi | 4 +-- propan/brokers/kafka/schemas.py | 2 +- propan/brokers/model/__init__.py | 4 --- propan/brokers/nats/nats_broker.py | 4 +-- propan/brokers/nats/nats_broker.pyi | 4 +-- propan/brokers/nats/schemas.py | 2 +- propan/brokers/rabbit/rabbit_broker.py | 4 +-- propan/brokers/rabbit/rabbit_broker.pyi | 4 +-- propan/brokers/rabbit/schemas.py | 2 +- propan/brokers/redis/redis_broker.py | 4 +-- propan/brokers/redis/redis_broker.pyi | 4 +-- propan/brokers/redis/schemas.py | 2 +- propan/cli/app.py | 8 +++++ propan/cli/docs/app.py | 13 +++++++- propan/cli/docs/gen.py | 31 +++++++++++++++++-- propan/fastapi/core/route.py | 2 +- propan/fastapi/core/router.py | 2 +- propan/test/utils.py | 2 +- 35 files changed, 110 insertions(+), 47 deletions(-) create mode 100644 asyncapi.yaml create mode 100644 propan/asyncapi/info.py create mode 100644 propan/brokers/_model/__init__.py rename propan/brokers/{model => _model}/broker_usecase.py (98%) rename propan/brokers/{model => _model}/schemas.py (100%) rename propan/brokers/{model => _model}/utils.py (100%) delete mode 100644 propan/brokers/model/__init__.py diff --git a/asyncapi.yaml b/asyncapi.yaml new file mode 100644 index 00000000..3d005259 --- /dev/null +++ b/asyncapi.yaml @@ -0,0 +1,6 @@ +asyncapi: 2.6.0 +defaultContentType: application/json +info: + title: PropanApp + version: 1.0.0 + description: '' diff --git a/docs/docs_src/contributing/adapter/parent.py b/docs/docs_src/contributing/adapter/parent.py index 8a93d15e..ef63f016 100644 --- a/docs/docs_src/contributing/adapter/parent.py +++ b/docs/docs_src/contributing/adapter/parent.py @@ -1,7 +1,7 @@ from typing import Any, Callable, Optional, TypeVar -from propan.brokers.model import BrokerUsecase -from propan.brokers.model.schemas import PropanMessage +from propan.brokers._model import BrokerUsecase +from propan.brokers._model.schemas import PropanMessage from propan.brokers.push_back_watcher import BaseWatcher from propan.types import HandlerWrapper, SendableMessage diff --git a/docs/docs_src/contributing/adapter/rabbit_connect.py b/docs/docs_src/contributing/adapter/rabbit_connect.py index 6e7668e7..3c824381 100644 --- a/docs/docs_src/contributing/adapter/rabbit_connect.py +++ b/docs/docs_src/contributing/adapter/rabbit_connect.py @@ -3,7 +3,7 @@ import aio_pika -from propan.brokers.model import BrokerUsecase +from propan.brokers._model import BrokerUsecase class RabbitBroker(BrokerUsecase): _connection: Optional[aio_pika.RobustConnection] diff --git a/docs/docs_src/contributing/adapter/rabbit_handle.py b/docs/docs_src/contributing/adapter/rabbit_handle.py index 2da77d4d..14e95c7d 100644 --- a/docs/docs_src/contributing/adapter/rabbit_handle.py +++ b/docs/docs_src/contributing/adapter/rabbit_handle.py @@ -2,8 +2,8 @@ from typing import List, Union, Optional from propan.types import HandlerWrapper, HandlerCallable -from propan.brokers.model import BrokerUsecase -from propan.brokers.model.schemas import BaseHandler +from propan.brokers._model import BrokerUsecase +from propan.brokers._model.schemas import BaseHandler from propan.brokers.rabbit import RabbitExchange, RabbitQueue diff --git a/docs/docs_src/contributing/adapter/rabbit_init.py b/docs/docs_src/contributing/adapter/rabbit_init.py index 1b8edc34..8682b539 100644 --- a/docs/docs_src/contributing/adapter/rabbit_init.py +++ b/docs/docs_src/contributing/adapter/rabbit_init.py @@ -1,6 +1,6 @@ from typing import Any, Optional -from propan.brokers.model import BrokerUsecase +from propan.brokers._model import BrokerUsecase class RabbitBroker(BrokerUsecase): diff --git a/docs/docs_src/contributing/adapter/rabbit_parse.py b/docs/docs_src/contributing/adapter/rabbit_parse.py index 79a815fa..6ef4c0b8 100644 --- a/docs/docs_src/contributing/adapter/rabbit_parse.py +++ b/docs/docs_src/contributing/adapter/rabbit_parse.py @@ -1,7 +1,7 @@ import aio_pika -from propan.brokers.model import BrokerUsecase -from propan.brokers.model.schemas import PropanMessage +from propan.brokers._model import BrokerUsecase +from propan.brokers._model.schemas import PropanMessage class RabbitBroker(BrokerUsecase): diff --git a/docs/docs_src/contributing/adapter/rabbit_process.py b/docs/docs_src/contributing/adapter/rabbit_process.py index 964e99cb..92355a58 100644 --- a/docs/docs_src/contributing/adapter/rabbit_process.py +++ b/docs/docs_src/contributing/adapter/rabbit_process.py @@ -1,8 +1,8 @@ from functools import wraps from typing import Optional, TypeVar, Callable -from propan.brokers.model import BrokerUsecase -from propan.brokers.model.schemas import PropanMessage +from propan.brokers._model import BrokerUsecase +from propan.brokers._model.schemas import PropanMessage from propan.brokers.push_back_watcher import BaseWatcher, WatcherContext T = TypeVar("T") diff --git a/docs/docs_src/contributing/adapter/redis_process.py b/docs/docs_src/contributing/adapter/redis_process.py index 5f0d3c9d..def64ebb 100644 --- a/docs/docs_src/contributing/adapter/redis_process.py +++ b/docs/docs_src/contributing/adapter/redis_process.py @@ -1,8 +1,8 @@ from functools import wraps from typing import Optional, TypeVar, Callable -from propan.brokers.model import BrokerUsecase -from propan.brokers.model.schemas import PropanMessage +from propan.brokers._model import BrokerUsecase +from propan.brokers._model.schemas import PropanMessage from propan.brokers.push_back_watcher import BaseWatcher T = TypeVar("T") diff --git a/docs/docs_src/contributing/adapter/redis_publish.py b/docs/docs_src/contributing/adapter/redis_publish.py index 11e25f2f..3f166cfd 100644 --- a/docs/docs_src/contributing/adapter/redis_publish.py +++ b/docs/docs_src/contributing/adapter/redis_publish.py @@ -1,7 +1,7 @@ from typing import Optional, Dict, Any from propan.types import SendableMessage -from propan.brokers.model import BrokerUsecase +from propan.brokers._model import BrokerUsecase from propan.brokers.redis.schemas import RedisMessage diff --git a/docs/docs_src/contributing/adapter/redis_start.py b/docs/docs_src/contributing/adapter/redis_start.py index 2f528cce..f3d84d28 100644 --- a/docs/docs_src/contributing/adapter/redis_start.py +++ b/docs/docs_src/contributing/adapter/redis_start.py @@ -4,7 +4,7 @@ from redis.asyncio.client import PubSub, Redis -from propan.brokers.model import BrokerUsecase +from propan.brokers._model import BrokerUsecase @dataclass diff --git a/propan/asyncapi/__init__.py b/propan/asyncapi/__init__.py index b4cf27dc..49dd76ed 100644 --- a/propan/asyncapi/__init__.py +++ b/propan/asyncapi/__init__.py @@ -1,3 +1,7 @@ from propan.asyncapi.main import ASYNC_API_VERSION +from propan.asyncapi.info import AsyncAPIInfo -__all__ = ("ASYNC_API_VERSION",) +__all__ = ( + "ASYNC_API_VERSION", + "AsyncAPIInfo", +) diff --git a/propan/asyncapi/info.py b/propan/asyncapi/info.py new file mode 100644 index 00000000..57562a58 --- /dev/null +++ b/propan/asyncapi/info.py @@ -0,0 +1,7 @@ +from pydantic import BaseModel, Field + + +class AsyncAPIInfo(BaseModel): + title: str + version: str = Field(default="1.0.0") + description: str = "" diff --git a/propan/brokers/_model/__init__.py b/propan/brokers/_model/__init__.py new file mode 100644 index 00000000..a5f90832 --- /dev/null +++ b/propan/brokers/_model/__init__.py @@ -0,0 +1,4 @@ +from propan.brokers._model.broker_usecase import BrokerUsecase +from propan.brokers._model.schemas import ContentTypes, Queue + +__all__ = ("Queue", "BrokerUsecase", "ContentTypes") diff --git a/propan/brokers/model/broker_usecase.py b/propan/brokers/_model/broker_usecase.py similarity index 98% rename from propan/brokers/model/broker_usecase.py rename to propan/brokers/_model/broker_usecase.py index 0de521d7..b50251f2 100644 --- a/propan/brokers/model/broker_usecase.py +++ b/propan/brokers/_model/broker_usecase.py @@ -4,13 +4,13 @@ from functools import wraps from typing import Any, Awaitable, Callable, Dict, List, Optional, Tuple, TypeVar, Union -from propan.brokers.model.schemas import ( +from propan.brokers._model.schemas import ( ContentType, ContentTypes, PropanMessage, SendableModel, ) -from propan.brokers.model.utils import ( +from propan.brokers._model.utils import ( change_logger_handlers, get_watcher, set_message_context, diff --git a/propan/brokers/model/schemas.py b/propan/brokers/_model/schemas.py similarity index 100% rename from propan/brokers/model/schemas.py rename to propan/brokers/_model/schemas.py diff --git a/propan/brokers/model/utils.py b/propan/brokers/_model/utils.py similarity index 100% rename from propan/brokers/model/utils.py rename to propan/brokers/_model/utils.py diff --git a/propan/brokers/kafka/kafka_broker.py b/propan/brokers/kafka/kafka_broker.py index 266d751d..a1200112 100644 --- a/propan/brokers/kafka/kafka_broker.py +++ b/propan/brokers/kafka/kafka_broker.py @@ -8,8 +8,8 @@ from propan.__about__ import __version__ from propan.brokers.kafka.schemas import Handler -from propan.brokers.model.broker_usecase import BrokerUsecase -from propan.brokers.model.schemas import PropanMessage +from propan.brokers._model.broker_usecase import BrokerUsecase +from propan.brokers._model.schemas import PropanMessage from propan.brokers.push_back_watcher import BaseWatcher from propan.types import ( AnyCallable, diff --git a/propan/brokers/kafka/kafka_broker.pyi b/propan/brokers/kafka/kafka_broker.pyi index 04238b11..5492bb57 100644 --- a/propan/brokers/kafka/kafka_broker.pyi +++ b/propan/brokers/kafka/kafka_broker.pyi @@ -14,8 +14,8 @@ from typing_extensions import Literal, TypeVar from propan.__about__ import __version__ from propan.brokers.kafka.schemas import Handler -from propan.brokers.model.broker_usecase import BrokerUsecase -from propan.brokers.model.schemas import PropanMessage +from propan.brokers._model.broker_usecase import BrokerUsecase +from propan.brokers._model.schemas import PropanMessage from propan.brokers.push_back_watcher import BaseWatcher from propan.log import access_logger from propan.types import SendableMessage, Wrapper diff --git a/propan/brokers/kafka/schemas.py b/propan/brokers/kafka/schemas.py index 3eb7f0fa..3ba1c215 100644 --- a/propan/brokers/kafka/schemas.py +++ b/propan/brokers/kafka/schemas.py @@ -4,7 +4,7 @@ from aiokafka import AIOKafkaConsumer -from propan.brokers.model.schemas import BaseHandler +from propan.brokers._model.schemas import BaseHandler from propan.types import AnyDict diff --git a/propan/brokers/model/__init__.py b/propan/brokers/model/__init__.py deleted file mode 100644 index f1d2eba1..00000000 --- a/propan/brokers/model/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from propan.brokers.model.broker_usecase import BrokerUsecase -from propan.brokers.model.schemas import ContentTypes, Queue - -__all__ = ("Queue", "BrokerUsecase", "ContentTypes") diff --git a/propan/brokers/nats/nats_broker.py b/propan/brokers/nats/nats_broker.py index af90aca7..603dc00b 100644 --- a/propan/brokers/nats/nats_broker.py +++ b/propan/brokers/nats/nats_broker.py @@ -5,8 +5,8 @@ from nats.aio.client import Client from nats.aio.msg import Msg -from propan.brokers.model import BrokerUsecase -from propan.brokers.model.schemas import PropanMessage +from propan.brokers._model import BrokerUsecase +from propan.brokers._model.schemas import PropanMessage from propan.brokers.nats.schemas import Handler from propan.brokers.push_back_watcher import BaseWatcher from propan.types import AnyDict, DecoratedCallable, SendableMessage diff --git a/propan/brokers/nats/nats_broker.pyi b/propan/brokers/nats/nats_broker.pyi index aa05f58d..f5fff50d 100644 --- a/propan/brokers/nats/nats_broker.pyi +++ b/propan/brokers/nats/nats_broker.pyi @@ -21,8 +21,8 @@ from nats.aio.client import ( ) from nats.aio.msg import Msg -from propan.brokers.model import BrokerUsecase -from propan.brokers.model.schemas import PropanMessage +from propan.brokers._model import BrokerUsecase +from propan.brokers._model.schemas import PropanMessage from propan.brokers.nats.schemas import Handler from propan.brokers.push_back_watcher import BaseWatcher from propan.log import access_logger diff --git a/propan/brokers/nats/schemas.py b/propan/brokers/nats/schemas.py index d9d13c8c..3c3441e6 100644 --- a/propan/brokers/nats/schemas.py +++ b/propan/brokers/nats/schemas.py @@ -5,7 +5,7 @@ from nats.js.api import DEFAULT_PREFIX from pydantic import BaseModel -from propan.brokers.model.schemas import BaseHandler +from propan.brokers._model.schemas import BaseHandler @dataclass diff --git a/propan/brokers/rabbit/rabbit_broker.py b/propan/brokers/rabbit/rabbit_broker.py index 55b1bf45..64da36be 100644 --- a/propan/brokers/rabbit/rabbit_broker.py +++ b/propan/brokers/rabbit/rabbit_broker.py @@ -7,8 +7,8 @@ import aiormq from aio_pika.abc import DeliveryMode -from propan.brokers.model import BrokerUsecase -from propan.brokers.model.schemas import PropanMessage +from propan.brokers._model import BrokerUsecase +from propan.brokers._model.schemas import PropanMessage from propan.brokers.push_back_watcher import BaseWatcher, WatcherContext from propan.brokers.rabbit.schemas import Handler, RabbitExchange, RabbitQueue from propan.types import AnyDict, DecoratedCallable, HandlerWrapper, SendableMessage diff --git a/propan/brokers/rabbit/rabbit_broker.pyi b/propan/brokers/rabbit/rabbit_broker.pyi index b2d47072..0da9aed9 100644 --- a/propan/brokers/rabbit/rabbit_broker.pyi +++ b/propan/brokers/rabbit/rabbit_broker.pyi @@ -8,8 +8,8 @@ from pamqp.common import FieldTable from typing_extensions import ParamSpec from yarl import URL -from propan.brokers.model import BrokerUsecase -from propan.brokers.model.schemas import PropanMessage +from propan.brokers._model import BrokerUsecase +from propan.brokers._model.schemas import PropanMessage from propan.brokers.push_back_watcher import BaseWatcher from propan.brokers.rabbit.schemas import Handler, RabbitExchange, RabbitQueue from propan.log import access_logger diff --git a/propan/brokers/rabbit/schemas.py b/propan/brokers/rabbit/schemas.py index 01973f98..10bfdfea 100644 --- a/propan/brokers/rabbit/schemas.py +++ b/propan/brokers/rabbit/schemas.py @@ -4,7 +4,7 @@ from aio_pika.abc import ExchangeType, TimeoutType from pydantic import Field -from propan.brokers.model.schemas import BaseHandler, NameRequired, Queue +from propan.brokers._model.schemas import BaseHandler, NameRequired, Queue __all__ = ( "RabbitQueue", diff --git a/propan/brokers/redis/redis_broker.py b/propan/brokers/redis/redis_broker.py index cebf9e7e..50def764 100644 --- a/propan/brokers/redis/redis_broker.py +++ b/propan/brokers/redis/redis_broker.py @@ -6,8 +6,8 @@ from redis.asyncio.client import PubSub, Redis -from propan.brokers.model import BrokerUsecase -from propan.brokers.model.schemas import PropanMessage, RawDecoced +from propan.brokers._model import BrokerUsecase +from propan.brokers._model.schemas import PropanMessage, RawDecoced from propan.brokers.push_back_watcher import BaseWatcher from propan.brokers.redis.schemas import Handler, RedisMessage from propan.types import ( diff --git a/propan/brokers/redis/redis_broker.pyi b/propan/brokers/redis/redis_broker.pyi index 68665794..29859187 100644 --- a/propan/brokers/redis/redis_broker.pyi +++ b/propan/brokers/redis/redis_broker.pyi @@ -4,8 +4,8 @@ from typing import Any, Callable, Dict, List, Mapping, Optional, Type, TypeVar, from redis.asyncio.client import Redis from redis.asyncio.connection import BaseParser, Connection, DefaultParser, Encoder -from propan.brokers.model import BrokerUsecase -from propan.brokers.model.schemas import PropanMessage +from propan.brokers._model import BrokerUsecase +from propan.brokers._model.schemas import PropanMessage from propan.brokers.push_back_watcher import BaseWatcher from propan.brokers.redis.schemas import Handler from propan.log import access_logger diff --git a/propan/brokers/redis/schemas.py b/propan/brokers/redis/schemas.py index 212fdc01..50c83554 100644 --- a/propan/brokers/redis/schemas.py +++ b/propan/brokers/redis/schemas.py @@ -5,7 +5,7 @@ from pydantic import BaseModel, Field from redis.asyncio.client import PubSub -from propan.brokers.model.schemas import BaseHandler +from propan.brokers._model.schemas import BaseHandler @dataclass diff --git a/propan/cli/app.py b/propan/cli/app.py index 0059d8e4..91db1699 100644 --- a/propan/cli/app.py +++ b/propan/cli/app.py @@ -35,6 +35,10 @@ def __init__( self, broker: Optional[Runnable] = None, logger: Optional[logging.Logger] = logger, + # AsyncAPI args, + title: str = "PropanApp", + version: str = "1.0.0", + description: str = "", ): self.broker = broker self.logger = logger @@ -49,6 +53,10 @@ def __init__( self._receive_stream = None self._command_line_options: Dict[str, SettingField] = {} + self.title = title + self.version = version + self.description = description + def set_broker(self, broker: Runnable) -> None: self.broker = broker diff --git a/propan/cli/docs/app.py b/propan/cli/docs/app.py index de241ada..0263f014 100644 --- a/propan/cli/docs/app.py +++ b/propan/cli/docs/app.py @@ -1,4 +1,5 @@ import sys +from pathlib import Path import typer @@ -13,11 +14,21 @@ def gen( app: str = typer.Argument( ..., help="[python_module:PropanApp] - path to your application" ), + filename: str = typer.Option( + "asyncapi.yaml", + "-f", "--f", + case_sensitive=False, + show_default=True, + help="generated document filename", + ), ) -> None: """Generate an AsyncAPI schema.yaml for your project""" + current_dir = Path.cwd() + generated_filepath = current_dir / filename + module, app = get_app_path(app) app_dir = module.parent sys.path.insert(0, str(app_dir)) propan_app = try_import_propan(module, app) - generate_doc_file(propan_app) + generate_doc_file(propan_app, generated_filepath) diff --git a/propan/cli/docs/gen.py b/propan/cli/docs/gen.py index 5772bfdc..bd82d4cb 100644 --- a/propan/cli/docs/gen.py +++ b/propan/cli/docs/gen.py @@ -1,7 +1,34 @@ +from pathlib import Path + import typer +import yaml +from propan.brokers._model.schemas import ContentTypes +from propan.asyncapi import ASYNC_API_VERSION, AsyncAPIInfo from propan.cli.app import PropanApp +from propan.types import AnyDict + + +def generate_doc_file(app: PropanApp, filename: Path) -> None: + schema = get_app_schema(app) + with filename.open("w") as f: + yaml.dump(schema, f, sort_keys=False) + typer.echo(f"Your project AsyncAPI schema was placed to `{filename}`") + + +def get_app_schema(app: PropanApp) -> AnyDict: + schema = { + "asyncapi": ASYNC_API_VERSION, + "info": _get_app_info(app), + "defaultContentType": ContentTypes.json.value, + } + + return schema -def generate_doc_file(app: PropanApp) -> None: - typer.echo(app) +def _get_app_info(app: PropanApp) -> AnyDict: + return AsyncAPIInfo( + title=app.title, + version=app.version, + description=app.description, + ).dict() diff --git a/propan/fastapi/core/route.py b/propan/fastapi/core/route.py index 66b8f546..efc6a62f 100644 --- a/propan/fastapi/core/route.py +++ b/propan/fastapi/core/route.py @@ -10,7 +10,7 @@ from starlette.requests import Request from starlette.routing import BaseRoute -from propan.brokers.model import BrokerUsecase +from propan.brokers._model import BrokerUsecase from propan.types import AnyDict NativeMessage = Union[str, AnyDict, bytes] diff --git a/propan/fastapi/core/router.py b/propan/fastapi/core/router.py index 897ebb17..6cf7ca57 100644 --- a/propan/fastapi/core/router.py +++ b/propan/fastapi/core/router.py @@ -11,7 +11,7 @@ from starlette.types import ASGIApp from typing_extensions import ClassVar -from propan.brokers.model import BrokerUsecase +from propan.brokers._model import BrokerUsecase from propan.fastapi.core.route import PropanRoute from propan.types import AnyDict diff --git a/propan/test/utils.py b/propan/test/utils.py index 6b8a40b9..bc889411 100644 --- a/propan/test/utils.py +++ b/propan/test/utils.py @@ -1,7 +1,7 @@ import asyncio from typing import Any, Optional -from propan.brokers.model.schemas import BaseHandler +from propan.brokers._model.schemas import BaseHandler async def call_handler( From 3120382d87d4d6e567817ec28aac0caafb0d08a3 Mon Sep 17 00:00:00 2001 From: Lancetnik Date: Thu, 1 Jun 2023 21:59:38 +0300 Subject: [PATCH 03/18] generate project servers --- asyncapi.yaml | 4 ++ asyncapi_docs/rpc_client.yaml | 69 +++++++++++++++++++++++++ asyncapi_docs/rpc_server.yaml | 66 +++++++++++++++++++++++ propan/asyncapi/__init__.py | 3 ++ propan/asyncapi/info.py | 4 +- propan/asyncapi/servers.py | 6 +++ propan/brokers/_model/broker_usecase.py | 6 +++ propan/brokers/rabbit/rabbit_broker.py | 11 +++- propan/brokers/rabbit/rabbit_broker.pyi | 2 + propan/cli/docs/gen.py | 20 ++++++- 10 files changed, 186 insertions(+), 5 deletions(-) create mode 100644 asyncapi_docs/rpc_client.yaml create mode 100644 asyncapi_docs/rpc_server.yaml create mode 100644 propan/asyncapi/servers.py diff --git a/asyncapi.yaml b/asyncapi.yaml index 3d005259..38c50150 100644 --- a/asyncapi.yaml +++ b/asyncapi.yaml @@ -4,3 +4,7 @@ info: title: PropanApp version: 1.0.0 description: '' +servers: + production: + url: amqp://localhost:6379 + protocol: amqp diff --git a/asyncapi_docs/rpc_client.yaml b/asyncapi_docs/rpc_client.yaml new file mode 100644 index 00000000..528b7ffa --- /dev/null +++ b/asyncapi_docs/rpc_client.yaml @@ -0,0 +1,69 @@ +asyncapi: '2.6.0' +id: 'urn:example:rpcclient' +defaultContentType: application/json + +info: + title: RPC Client Example + description: This example demonstrates how to define an RPC client. + version: '1.0.0' + +servers: + production: + url: rabbitmq.example.org + protocol: amqp + +channels: + '{queue}': + parameters: + queue: + schema: + type: string + pattern: '^amq\\.gen\\-.+$' + bindings: + amqp: + is: queue + queue: + exclusive: true + publish: + operationId: receiveSumResult + bindings: + amqp: + ack: false + message: + correlationId: + location: $message.header#/correlation_id + payload: + type: object + properties: + result: + type: number + examples: + - 7 + + rpc_queue: + bindings: + amqp: + is: queue + queue: + durable: false + subscribe: + operationId: requestSum + bindings: + amqp: + ack: true + message: + bindings: + amqp: + replyTo: + type: string + correlationId: + location: $message.header#/correlation_id + payload: + type: object + properties: + numbers: + type: array + items: + type: number + examples: + - [4,3] \ No newline at end of file diff --git a/asyncapi_docs/rpc_server.yaml b/asyncapi_docs/rpc_server.yaml new file mode 100644 index 00000000..5080c599 --- /dev/null +++ b/asyncapi_docs/rpc_server.yaml @@ -0,0 +1,66 @@ +asyncapi: '2.6.0' +id: 'urn:example:rpcserver' +defaultContentType: application/json + +info: + title: RPC Server Example + description: This example demonstrates how to define an RPC server. + version: '1.0.0' + +servers: + production: + url: rabbitmq.example.org + protocol: amqp + +channels: + '{queue}': + parameters: + queue: + schema: + type: string + pattern: '^amq\\.gen\\-.+$' + bindings: + amqp: + is: queue + queue: + exclusive: true + subscribe: + operationId: sendSumResult + bindings: + amqp: + ack: true + message: + correlationId: + location: $message.header#/correlation_id + payload: + type: object + properties: + result: + type: number + examples: + - 7 + + rpc_queue: + bindings: + amqp: + is: queue + queue: + durable: false + publish: + operationId: sum + message: + bindings: + amqp: + replyTo: + type: string + correlationId: + location: $message.header#/correlation_id + payload: + type: object + properties: + numbers: + type: array + items: + type: number + examples: + - [4,3] \ No newline at end of file diff --git a/propan/asyncapi/__init__.py b/propan/asyncapi/__init__.py index 49dd76ed..a31c04d7 100644 --- a/propan/asyncapi/__init__.py +++ b/propan/asyncapi/__init__.py @@ -1,7 +1,10 @@ from propan.asyncapi.main import ASYNC_API_VERSION from propan.asyncapi.info import AsyncAPIInfo +from propan.asyncapi.servers import AsyncAPIServer + __all__ = ( "ASYNC_API_VERSION", "AsyncAPIInfo", + "AsyncAPIServer", ) diff --git a/propan/asyncapi/info.py b/propan/asyncapi/info.py index 57562a58..8392db67 100644 --- a/propan/asyncapi/info.py +++ b/propan/asyncapi/info.py @@ -1,7 +1,7 @@ -from pydantic import BaseModel, Field +from pydantic import BaseModel class AsyncAPIInfo(BaseModel): title: str - version: str = Field(default="1.0.0") + version: str = "1.0.0" description: str = "" diff --git a/propan/asyncapi/servers.py b/propan/asyncapi/servers.py new file mode 100644 index 00000000..56c230be --- /dev/null +++ b/propan/asyncapi/servers.py @@ -0,0 +1,6 @@ +from pydantic import BaseModel + + +class AsyncAPIServer(BaseModel): + url: str + protocol: str diff --git a/propan/brokers/_model/broker_usecase.py b/propan/brokers/_model/broker_usecase.py index b50251f2..7ef3a3e6 100644 --- a/propan/brokers/_model/broker_usecase.py +++ b/propan/brokers/_model/broker_usecase.py @@ -48,6 +48,9 @@ def __init__( logger: Optional[logging.Logger] = access_logger, log_level: int = logging.INFO, log_fmt: Optional[str] = "%(asctime)s %(levelname)s - %(message)s", + # AsyncAPI + protocol: str = "", + url: str = "", **kwargs: Any, ) -> None: self.logger = logger @@ -64,6 +67,9 @@ def __init__( context.set_global("logger", logger) context.set_global("broker", self) + self.protocol = protocol + self.url = url + async def connect(self, *args: Any, **kwargs: Any) -> Any: if self._connection is None: _args = args or self._connection_args diff --git a/propan/brokers/rabbit/rabbit_broker.py b/propan/brokers/rabbit/rabbit_broker.py index 64da36be..d99679a4 100644 --- a/propan/brokers/rabbit/rabbit_broker.py +++ b/propan/brokers/rabbit/rabbit_broker.py @@ -28,12 +28,21 @@ class RabbitBroker(BrokerUsecase): def __init__( self, + url: Optional[str] = None, *args: Tuple[Any, ...], + protocol: str = "amqp", consumers: Optional[int] = None, log_fmt: Optional[str] = None, **kwargs: AnyDict, ) -> None: - super().__init__(*args, log_fmt=log_fmt, **kwargs) + super().__init__( + url, + *args, + log_fmt=log_fmt, + protocol=protocol, + url=url, + **kwargs, + ) self._max_consumers = consumers self._channel = None diff --git a/propan/brokers/rabbit/rabbit_broker.pyi b/propan/brokers/rabbit/rabbit_broker.pyi index 0da9aed9..0f676fdb 100644 --- a/propan/brokers/rabbit/rabbit_broker.pyi +++ b/propan/brokers/rabbit/rabbit_broker.pyi @@ -46,6 +46,8 @@ class RabbitBroker(BrokerUsecase): log_fmt: Optional[str] = None, apply_types: bool = True, consumers: Optional[int] = None, + # AsyncAPI + protocol: str = "amqp", ) -> None: """ URL string might be contain ssl parameters e.g. diff --git a/propan/cli/docs/gen.py b/propan/cli/docs/gen.py index bd82d4cb..abf7bbe5 100644 --- a/propan/cli/docs/gen.py +++ b/propan/cli/docs/gen.py @@ -3,13 +3,18 @@ import typer import yaml +from propan.brokers._model import BrokerUsecase from propan.brokers._model.schemas import ContentTypes -from propan.asyncapi import ASYNC_API_VERSION, AsyncAPIInfo +from propan.asyncapi import (ASYNC_API_VERSION, AsyncAPIInfo, AsyncAPIServer,) from propan.cli.app import PropanApp from propan.types import AnyDict def generate_doc_file(app: PropanApp, filename: Path) -> None: + if app.broker is None: + typer.echo("Your PropanApp has no broker") + raise typer.Exit() + schema = get_app_schema(app) with filename.open("w") as f: yaml.dump(schema, f, sort_keys=False) @@ -19,8 +24,9 @@ def generate_doc_file(app: PropanApp, filename: Path) -> None: def get_app_schema(app: PropanApp) -> AnyDict: schema = { "asyncapi": ASYNC_API_VERSION, - "info": _get_app_info(app), "defaultContentType": ContentTypes.json.value, + "info": _get_app_info(app), + "servers": _get_broker_servers(app.broker), } return schema @@ -32,3 +38,13 @@ def _get_app_info(app: PropanApp) -> AnyDict: version=app.version, description=app.description, ).dict() + + +def _get_broker_servers(broker: BrokerUsecase) -> AnyDict: + return { + "production": AsyncAPIServer( + url=broker.url, + protocol=broker.protocol, + ).dict() + } + From 816ff91618739cff3b1750bcac3179845ef061e2 Mon Sep 17 00:00:00 2001 From: Lancetnik Date: Thu, 1 Jun 2023 22:39:56 +0300 Subject: [PATCH 04/18] generate handler raw --- asyncapi.yaml | 10 --------- propan/brokers/_model/broker_usecase.py | 3 ++- propan/brokers/_model/schemas.py | 11 +++++++++- propan/brokers/rabbit/rabbit_broker.py | 8 +++++++- propan/brokers/rabbit/rabbit_broker.pyi | 2 ++ propan/brokers/rabbit/schemas.py | 27 ++++++++++++++++++++++--- propan/cli/docs/gen.py | 8 ++++++++ 7 files changed, 53 insertions(+), 16 deletions(-) delete mode 100644 asyncapi.yaml diff --git a/asyncapi.yaml b/asyncapi.yaml deleted file mode 100644 index 38c50150..00000000 --- a/asyncapi.yaml +++ /dev/null @@ -1,10 +0,0 @@ -asyncapi: 2.6.0 -defaultContentType: application/json -info: - title: PropanApp - version: 1.0.0 - description: '' -servers: - production: - url: amqp://localhost:6379 - protocol: amqp diff --git a/propan/brokers/_model/broker_usecase.py b/propan/brokers/_model/broker_usecase.py index 7ef3a3e6..6f85b707 100644 --- a/propan/brokers/_model/broker_usecase.py +++ b/propan/brokers/_model/broker_usecase.py @@ -9,6 +9,7 @@ ContentTypes, PropanMessage, SendableModel, + BaseHandler, ) from propan.brokers._model.utils import ( change_logger_handlers, @@ -37,7 +38,7 @@ class BrokerUsecase(ABC): logger: Optional[logging.Logger] log_level: int - handlers: List[Any] + handlers: List[BaseHandler] _connection: Any _fmt: Optional[str] diff --git a/propan/brokers/_model/schemas.py b/propan/brokers/_model/schemas.py index b4632c89..764bb3b6 100644 --- a/propan/brokers/_model/schemas.py +++ b/propan/brokers/_model/schemas.py @@ -1,5 +1,5 @@ import json -from dataclasses import dataclass +from dataclasses import dataclass, field from enum import Enum from typing import Any, Dict, Optional, Sequence, Tuple, Union from uuid import uuid4 @@ -7,6 +7,8 @@ from pydantic import BaseModel, Field, Json from pydantic.dataclasses import dataclass as pydantic_dataclass from typing_extensions import TypeAlias, assert_never +from fast_depends.construct import get_dependant +from fast_depends.model import Dependant from propan.types import AnyDict, DecodedMessage, DecoratedCallable, SendableMessage @@ -16,6 +18,13 @@ @dataclass class BaseHandler: callback: DecoratedCallable + description: str = field(default="", kw_only=True) + + def get_schema(self) -> Tuple[str, AnyDict]: + return self.callback.__name__, {} + + def get_dependant(self) -> Dependant: + return get_dependant(path="", call=self.callback) class ContentTypes(str, Enum): diff --git a/propan/brokers/rabbit/rabbit_broker.py b/propan/brokers/rabbit/rabbit_broker.py index d99679a4..8dd6bc0c 100644 --- a/propan/brokers/rabbit/rabbit_broker.py +++ b/propan/brokers/rabbit/rabbit_broker.py @@ -85,6 +85,7 @@ def handle( exchange: Union[str, RabbitExchange, None] = None, *, retry: Union[bool, int] = False, + description: str = "", ) -> HandlerWrapper: queue, exchange = _validate_queue(queue), _validate_exchange(exchange) @@ -97,7 +98,12 @@ def wrapper(func: DecoratedCallable) -> Any: exchange=exchange, retry=retry, ) - handler = Handler(callback=func, queue=queue, exchange=exchange) + handler = Handler( + callback=func, + queue=queue, + exchange=exchange, + description=description, + ) self.handlers.append(handler) return func diff --git a/propan/brokers/rabbit/rabbit_broker.pyi b/propan/brokers/rabbit/rabbit_broker.pyi index 0f676fdb..ec46d35f 100644 --- a/propan/brokers/rabbit/rabbit_broker.pyi +++ b/propan/brokers/rabbit/rabbit_broker.pyi @@ -143,6 +143,8 @@ class RabbitBroker(BrokerUsecase): exchange: Union[str, RabbitExchange, None] = None, *, retry: Union[bool, int] = False, + # AsyncAPI + description: str = "", ) -> Callable[ [ Callable[ diff --git a/propan/brokers/rabbit/schemas.py b/propan/brokers/rabbit/schemas.py index 10bfdfea..68de5a86 100644 --- a/propan/brokers/rabbit/schemas.py +++ b/propan/brokers/rabbit/schemas.py @@ -1,10 +1,11 @@ -from dataclasses import dataclass -from typing import Any, Dict, Optional +from dataclasses import dataclass, field +from typing import Any, Dict, Optional, Tuple from aio_pika.abc import ExchangeType, TimeoutType from pydantic import Field from propan.brokers._model.schemas import BaseHandler, NameRequired, Queue +from propan.types import AnyDict __all__ = ( "RabbitQueue", @@ -50,4 +51,24 @@ class RabbitExchange(NameRequired): @dataclass class Handler(BaseHandler): queue: RabbitQueue - exchange: Optional[RabbitExchange] = None + exchange: Optional[RabbitExchange] = field(default=None, kw_only=True) + + def get_schema(self) -> Tuple[str, AnyDict]: + dependant = self.get_dependant() + + payload_type: str + if not dependant.params: + payload_type = "null" + else: + payload_type = "string" + + return self.callback.__name__, { + "subscribe": { + "description": self.description or self.callback.__doc__ or "", + "message": { + "payload": { + "type": payload_type + } + } + } + } diff --git a/propan/cli/docs/gen.py b/propan/cli/docs/gen.py index abf7bbe5..46764e60 100644 --- a/propan/cli/docs/gen.py +++ b/propan/cli/docs/gen.py @@ -27,6 +27,7 @@ def get_app_schema(app: PropanApp) -> AnyDict: "defaultContentType": ContentTypes.json.value, "info": _get_app_info(app), "servers": _get_broker_servers(app.broker), + "channels": _get_broker_channels(app.broker), } return schema @@ -48,3 +49,10 @@ def _get_broker_servers(broker: BrokerUsecase) -> AnyDict: ).dict() } + +def _get_broker_channels(broker: BrokerUsecase) -> AnyDict: + channels = {} + for handler in broker.handlers: + name, data = handler.get_schema() + channels[name] = data + return channels From d2a718f21f12c48b4e895c9def6c8a22a3c73601 Mon Sep 17 00:00:00 2001 From: Lancetnik Date: Sat, 3 Jun 2023 13:46:26 +0300 Subject: [PATCH 05/18] Close (#34): Autogenerate AsyncAPI payload examples --- .gitignore | 3 +- propan/asyncapi/utils.py | 24 +++++++++++++++- propan/brokers/_model/schemas.py | 48 ++++++++++++++++++++------------ propan/brokers/rabbit/schemas.py | 3 +- pyproject.toml | 1 + 5 files changed, 58 insertions(+), 21 deletions(-) diff --git a/.gitignore b/.gitignore index 12486d67..861de8d5 100644 --- a/.gitignore +++ b/.gitignore @@ -18,4 +18,5 @@ wtf coverage.json site Dockerfile -t \ No newline at end of file +t +asyncapi.yaml \ No newline at end of file diff --git a/propan/asyncapi/utils.py b/propan/asyncapi/utils.py index 5b621153..31e26cc6 100644 --- a/propan/asyncapi/utils.py +++ b/propan/asyncapi/utils.py @@ -1,6 +1,8 @@ -from typing import Optional +import json +from typing import Optional, Type from pydantic import BaseModel, Field +from polyfactory.factories.pydantic_factory import ModelFactory class AsyncAPIExternalDocs(BaseModel): @@ -18,3 +20,23 @@ class AsyncAPITag(BaseModel): class Config: allow_population_by_field_name = True + + +def add_example_to_model(model: Type[BaseModel]) -> Type[BaseModel]: + factory = type(f"{model.__name__}_factory", (ModelFactory,), {"__model__": model}) + + return type( + model.__name__, + (model,), + { + "Config": type( + "Config", + (model.Config,), + { + "schema_extra": { + "example": json.loads(factory.build().json()), + }, + }, + ) + }, + ) diff --git a/propan/brokers/_model/schemas.py b/propan/brokers/_model/schemas.py index 56cd7680..1cf37e8a 100644 --- a/propan/brokers/_model/schemas.py +++ b/propan/brokers/_model/schemas.py @@ -11,6 +11,7 @@ from typing_extensions import TypeAlias, assert_never from propan.asyncapi.channels import AsyncAPIChannel +from propan.asyncapi.utils import add_example_to_model from propan.types import AnyDict, DecodedMessage, DecoratedCallable, SendableMessage ContentType: TypeAlias = str @@ -29,7 +30,7 @@ def get_schema(self) -> Dict[str, AsyncAPIChannel]: def title(self) -> str: return self.callback.__name__.replace("_", " ").title().replace(" ", "") - def get_message_object(self) -> AnyDict: + def get_message_object(self) -> Tuple[str, AnyDict]: dependant = get_dependant(path="", call=self.callback) custom = tuple(c.param_name for c in dependant.custom) dependant.params = tuple( @@ -41,33 +42,44 @@ def get_message_object(self) -> AnyDict: # TODO: return RPC response class too params_number = len(dependant.params) + gen_examples: bool if params_number == 0: - body = {"title": schema_title, "type": "null"} + model = None + + elif params_number == 1: + param = dependant.params[0] + + if issubclass(param.annotation, BaseModel): + model = param.annotation + gen_examples = model.Config.schema_extra.get("example") is None + + else: + model = create_model( + schema_title, + **{ + param.name: (param.annotation, ... if param.required else param.default) + }, + ) + gen_examples = True else: - schema = create_model( # type: ignore + model = create_model( # type: ignore schema_title, **{ p.name: (p.annotation, ... if p.required else p.default) for p in dependant.params }, - ).schema() - - if params_number == 1: - body = tuple(schema.get("properties", {}).values())[0] + ) + gen_examples = True - ref = body.get("$ref") - if ref is not None: - key = ref.split("/")[-1] - body = schema.get("definitions", {}).get(key, {}) - - else: - body["title"] = schema_title - - else: - body = schema + if model is None: + body = {"title": schema_title, "type": "null"} + else: + if gen_examples is True: + model = add_example_to_model(model) + body = model.schema() - return body + return body.get("title", schema_title), body class ContentTypes(str, Enum): diff --git a/propan/brokers/rabbit/schemas.py b/propan/brokers/rabbit/schemas.py index 81108a9a..c49b2eff 100644 --- a/propan/brokers/rabbit/schemas.py +++ b/propan/brokers/rabbit/schemas.py @@ -117,7 +117,7 @@ class Handler(BaseHandler): exchange: Optional[RabbitExchange] = field(default=None, kw_only=True) # type: ignore def get_schema(self) -> Dict[str, AsyncAPIChannel]: - body = self.get_message_object() + message_title, body = self.get_message_object() return { self.title: AsyncAPIChannel( @@ -135,6 +135,7 @@ def get_schema(self) -> Dict[str, AsyncAPIChannel]: ) ), message=AsyncAPIMessage( + name=message_title, payload=body, correlation_id=AsyncAPICorrelationId( location="$message.header#/correlation_id" diff --git a/pyproject.toml b/pyproject.toml index 8555e0c5..3e85a000 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -80,6 +80,7 @@ async-kafka = [ doc = [ "PyYAML", "pytest[email]", + "polyfactory", ] async-sqs = [ From beaef9d094e0ad265f6614ca62fc482b30d679ef Mon Sep 17 00:00:00 2001 From: Lancetnik Date: Sat, 3 Jun 2023 14:59:52 +0300 Subject: [PATCH 06/18] Close (#33): Add RPC response information to AsyncAPI scheme --- propan/asyncapi/bindings/amqp.py | 6 ++++++ propan/brokers/_model/schemas.py | 37 ++++++++++++++++++++++++++++---- propan/brokers/rabbit/schemas.py | 7 +++--- 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/propan/asyncapi/bindings/amqp.py b/propan/asyncapi/bindings/amqp.py index d1a66f7d..fe33eb37 100644 --- a/propan/asyncapi/bindings/amqp.py +++ b/propan/asyncapi/bindings/amqp.py @@ -3,6 +3,8 @@ from pydantic import BaseModel, Field from typing_extensions import Literal +from propan.types import AnyDict + class AsyncAPIAmqpQueue(BaseModel): name: str @@ -45,3 +47,7 @@ class Config: class AsyncAPIAmqpOperationBinding(BaseModel): cc: Optional[str] = None ack: bool = True + reply_to: Optional[AnyDict] = Field(default=None, alias="replyTo") + + class Config: + allow_population_by_field_name = True diff --git a/propan/brokers/_model/schemas.py b/propan/brokers/_model/schemas.py index 1cf37e8a..ddfbbde2 100644 --- a/propan/brokers/_model/schemas.py +++ b/propan/brokers/_model/schemas.py @@ -7,6 +7,7 @@ from fast_depends.construct import get_dependant from pydantic import BaseModel, Field, Json, create_model +from pydantic.schema import field_schema from pydantic.dataclasses import dataclass as pydantic_dataclass from typing_extensions import TypeAlias, assert_never @@ -30,16 +31,44 @@ def get_schema(self) -> Dict[str, AsyncAPIChannel]: def title(self) -> str: return self.callback.__name__.replace("_", " ").title().replace(" ", "") - def get_message_object(self) -> Tuple[str, AnyDict]: + def get_message_object(self) -> Tuple[str, AnyDict, Optional[AnyDict]]: dependant = get_dependant(path="", call=self.callback) + + if dependant.return_field: + return_field = dependant.return_field + + if issubclass(return_field.type_, BaseModel): + return_model = return_field.type_ + if return_model.Config.schema_extra.get("example") is None: + return_model = add_example_to_model(return_model) + return_info = return_model.schema() + return_info["examples"] = [return_info.pop("example")] + + else: + return_model = create_model( + f"{self.title}Reply", + **{ + return_field.name: (return_field.annotation, ...) + }, + ) + return_model = add_example_to_model(return_model) + return_info = return_model.schema() + return_info.pop("required") + return_info.update({ + "type": return_info.pop("properties", {}).get(return_field.name, {}).get("type"), + "examples": [return_info.pop("example", {}).get(return_field.name)] + }) + + else: + return_info = None + + # TODO: recursive schema generation custom = tuple(c.param_name for c in dependant.custom) dependant.params = tuple( filter(lambda x: x.name not in custom, dependant.params) ) schema_title = f"{self.title}Message" - # TODO: recursive schema generation - # TODO: return RPC response class too params_number = len(dependant.params) gen_examples: bool @@ -79,7 +108,7 @@ def get_message_object(self) -> Tuple[str, AnyDict]: model = add_example_to_model(model) body = model.schema() - return body.get("title", schema_title), body + return body.get("title", schema_title), body, return_info class ContentTypes(str, Enum): diff --git a/propan/brokers/rabbit/schemas.py b/propan/brokers/rabbit/schemas.py index c49b2eff..11ba643b 100644 --- a/propan/brokers/rabbit/schemas.py +++ b/propan/brokers/rabbit/schemas.py @@ -117,7 +117,7 @@ class Handler(BaseHandler): exchange: Optional[RabbitExchange] = field(default=None, kw_only=True) # type: ignore def get_schema(self) -> Dict[str, AsyncAPIChannel]: - message_title, body = self.get_message_object() + message_title, body, reply_to = self.get_message_object() return { self.title: AsyncAPIChannel( @@ -131,8 +131,9 @@ def get_schema(self) -> Dict[str, AsyncAPIChannel]: and self.exchange.type in (ExchangeType.FANOUT, ExchangeType.HEADERS) ) - else self.queue.name - ) + else self.queue.name, + reply_to=reply_to, + ), ), message=AsyncAPIMessage( name=message_title, From 2eb7e71c7427320b45bac9337c34b3273bb9136d Mon Sep 17 00:00:00 2001 From: Lancetnik Date: Sun, 4 Jun 2023 11:32:20 +0300 Subject: [PATCH 07/18] mv jsonref to `doc` dependencies --- propan/brokers/_model/schemas.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/propan/brokers/_model/schemas.py b/propan/brokers/_model/schemas.py index 7001649e..ebc22fc4 100644 --- a/propan/brokers/_model/schemas.py +++ b/propan/brokers/_model/schemas.py @@ -5,7 +5,6 @@ from typing import Any, Dict, Optional, Sequence, Tuple, Union from uuid import uuid4 -import jsonref from fast_depends.construct import get_dependant from pydantic import BaseModel, Field, Json, create_model from pydantic.dataclasses import dataclass as pydantic_dataclass @@ -32,6 +31,7 @@ def title(self) -> str: return self.callback.__name__.replace("_", " ").title().replace(" ", "") def get_message_object(self) -> Tuple[str, AnyDict, Optional[AnyDict]]: + import jsonref # hide it there to remove docs dependencies from main package dependant = get_dependant(path="", call=self.callback) if dependant.return_field: @@ -70,7 +70,7 @@ def get_message_object(self) -> Tuple[str, AnyDict, Optional[AnyDict]]: else: return_info = None - # TODO: recursive schema generation + # TODO: test recursive schema generation schema_title = f"{self.title}Message" params = dependant.flat_params params_number = len(params) From d0e4b83239f79128e067f88991d39d28b441c3c9 Mon Sep 17 00:00:00 2001 From: Lancetnik Date: Sun, 4 Jun 2023 11:33:45 +0300 Subject: [PATCH 08/18] mv polyfactory to `doc` dependencies --- propan/asyncapi/utils.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/propan/asyncapi/utils.py b/propan/asyncapi/utils.py index 5b9d60e6..e9b5531e 100644 --- a/propan/asyncapi/utils.py +++ b/propan/asyncapi/utils.py @@ -1,7 +1,6 @@ import json from typing import Optional, Type -from polyfactory.factories.pydantic_factory import ModelFactory from pydantic import BaseModel, Field @@ -23,6 +22,10 @@ class Config: def add_example_to_model(model: Type[BaseModel]) -> Type[BaseModel]: + from polyfactory.factories.pydantic_factory import ( + ModelFactory, + ) # mv it to hide from main dependencies + factory = type(f"{model.__name__}_factory", (ModelFactory,), {"__model__": model}) return type( From 78b40dd510c91fa0e8fc1c2ea08f539f76f8c848 Mon Sep 17 00:00:00 2001 From: Lancetnik Date: Mon, 5 Jun 2023 22:28:09 +0300 Subject: [PATCH 09/18] add doc serve command (#43) --- propan/cli/app.py | 4 ++-- propan/cli/docs/app.py | 26 +++++++++++++++++++++++++- propan/cli/docs/gen.py | 14 ++++++++++---- pyproject.toml | 2 ++ 4 files changed, 39 insertions(+), 7 deletions(-) diff --git a/propan/cli/app.py b/propan/cli/app.py index 91db1699..34bbb262 100644 --- a/propan/cli/app.py +++ b/propan/cli/app.py @@ -36,8 +36,8 @@ def __init__( broker: Optional[Runnable] = None, logger: Optional[logging.Logger] = logger, # AsyncAPI args, - title: str = "PropanApp", - version: str = "1.0.0", + title: str = "Propan", + version: str = "0.1.0", description: str = "", ): self.broker = broker diff --git a/propan/cli/docs/app.py b/propan/cli/docs/app.py index e32d414c..075c669f 100644 --- a/propan/cli/docs/app.py +++ b/propan/cli/docs/app.py @@ -3,9 +3,11 @@ import typer -from propan.cli.docs.gen import generate_doc_file +from propan.cli.docs.gen import generate_doc_file, get_schema_yaml +from propan.cli.docs.serve import serve_docs from propan.cli.utils.imports import get_app_path, try_import_propan + docs_app = typer.Typer(pretty_exceptions_short=True) @@ -33,3 +35,25 @@ def gen( propan_app = try_import_propan(module, app) generate_doc_file(propan_app, generated_filepath) + + +@docs_app.command(name="serve") +def serve( + app: str = typer.Argument( + ..., help="[python_module:PropanApp] - path to your application" + ), + host: str = typer.Option( + "localhost", help="documentation hosting address" + ), + port: int = typer.Option( + 8000, help="documentation hosting port" + ) +) -> None: + """Serve project AsyncAPI scheme""" + module, app = get_app_path(app) + app_dir = module.parent + sys.path.insert(0, str(app_dir)) + propan_app = try_import_propan(module, app) + + schema = get_schema_yaml(propan_app) + serve_docs(schema, host, port) diff --git a/propan/cli/docs/gen.py b/propan/cli/docs/gen.py index 500cbd41..95db77fa 100644 --- a/propan/cli/docs/gen.py +++ b/propan/cli/docs/gen.py @@ -1,5 +1,6 @@ from pathlib import Path from typing import Dict +from io import StringIO import typer @@ -14,6 +15,12 @@ def generate_doc_file(app: PropanApp, filename: Path) -> None: + schema = get_schema_yaml(app) + filename.write_text(schema) + typer.echo(f"Your project AsyncAPI schema was placed to `{filename}`") + + +def get_schema_yaml(app: PropanApp) -> str: try: import yaml except ImportError as e: @@ -32,10 +39,9 @@ def generate_doc_file(app: PropanApp, filename: Path) -> None: exclude_none=True, ) - with filename.open("w") as f: - yaml.dump(schema, f, sort_keys=False) - - typer.echo(f"Your project AsyncAPI schema was placed to `{filename}`") + io = StringIO(initial_value="", newline="\n") + yaml.dump(schema, io, sort_keys=False) + return io.getvalue() def get_app_schema(app: PropanApp) -> AsyncAPISchema: diff --git a/pyproject.toml b/pyproject.toml index 9766a222..cd2e7723 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -82,6 +82,8 @@ doc = [ "pytest[email]", "polyfactory", "jsonref", + "fastapi", + "uvicorn", ] async-sqs = [ From 071e4dbc7a43ca0fc9071312e1511f973fb6943f Mon Sep 17 00:00:00 2001 From: Lancetnik Date: Mon, 5 Jun 2023 22:38:01 +0300 Subject: [PATCH 10/18] add dependencies arguments to main scheme (#36, #32) --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index cd2e7723..8318c3bd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -43,7 +43,7 @@ classifiers = [ ] dependencies = [ - "fast-depends>=1.1.5", + "fast-depends==1.1.6", "watchfiles", "typer", "uvloop>=0.14.0,!=0.15.0,!=0.15.1; sys_platform != 'win32' and (sys_platform != 'cygwin' and platform_python_implementation != 'PyPy')", From 44c2a71649a6ff63240acbeb0b07ffd0737613c5 Mon Sep 17 00:00:00 2001 From: Lancetnik Date: Wed, 7 Jun 2023 21:02:00 +0300 Subject: [PATCH 11/18] big asyncapi update (#32, #37, #38, #39, #40, #41, #46) --- docs/docs/ru/index.md | 2 +- propan/asyncapi/__init__.py | 9 +- propan/asyncapi/bindings/amqp.py | 8 +- propan/asyncapi/bindings/kafka.py | 41 ++++ propan/asyncapi/bindings/main.py | 24 +++ propan/asyncapi/bindings/nats.py | 28 +++ propan/asyncapi/bindings/redis.py | 29 +++ propan/asyncapi/bindings/sqs.py | 28 +++ propan/asyncapi/channels.py | 1 + propan/asyncapi/main.py | 25 ++- propan/asyncapi/message.py | 1 + propan/asyncapi/servers.py | 2 +- propan/asyncapi/utils.py | 44 ++-- propan/brokers/_model/broker_usecase.py | 41 +++- propan/brokers/_model/schemas.py | 49 +++-- propan/brokers/kafka/kafka_broker.py | 35 +++- propan/brokers/kafka/kafka_broker.pyi | 5 + propan/brokers/kafka/schemas.py | 50 ++++- propan/brokers/nats/nats_broker.py | 34 ++-- propan/brokers/nats/nats_broker.pyi | 7 +- propan/brokers/nats/schemas.py | 36 +++- propan/brokers/push_back_watcher.py | 2 +- propan/brokers/rabbit/rabbit_broker.py | 29 ++- propan/brokers/rabbit/rabbit_broker.pyi | 20 +- propan/brokers/rabbit/schemas.py | 24 ++- propan/brokers/redis/redis_broker.py | 25 ++- propan/brokers/redis/redis_broker.pyi | 20 +- propan/brokers/redis/schemas.py | 34 ++++ propan/brokers/sqs/schema.py | 36 ++++ propan/brokers/sqs/sqs_broker.py | 23 ++- propan/brokers/sqs/sqs_broker.pyi | 5 + propan/cli/app.py | 7 + propan/cli/docs/app.py | 32 +-- propan/cli/docs/gen.py | 59 ++++-- propan/cli/startproject/utils.py | 9 +- propan/cli/utils/imports.py | 5 +- propan/fastapi/kafka/router.pyi | 6 - propan/fastapi/nats/router.pyi | 6 - propan/fastapi/rabbit/router.pyi | 6 - propan/fastapi/redis/router.pyi | 6 - propan/fastapi/sqs/router.pyi | 6 - propan/utils/functions.py | 6 +- pyproject.toml | 1 + tests/asyncapi/__init__.py | 0 tests/asyncapi/handler/__init__.py | 0 tests/asyncapi/handler/test_base_arguments.py | 188 ++++++++++++++++++ .../handler/test_dependencies_arguments.py | 60 ++++++ tests/asyncapi/kafka/__init__.py | 0 tests/asyncapi/kafka/test_handler.py | 56 ++++++ tests/asyncapi/kafka/test_server.py | 28 +++ tests/asyncapi/nats/__init__.py | 0 tests/asyncapi/nats/test_handler.py | 61 ++++++ tests/asyncapi/nats/test_server.py | 10 + tests/asyncapi/rabbit/__init__.py | 0 tests/asyncapi/rabbit/test_handler.py | 115 +++++++++++ tests/asyncapi/rabbit/test_server.py | 26 +++ tests/asyncapi/redis/__init__.py | 0 tests/asyncapi/redis/test_handler.py | 68 +++++++ tests/asyncapi/redis/test_server.py | 10 + tests/asyncapi/sqs/__init__.py | 0 tests/asyncapi/sqs/test_handler.py | 66 ++++++ tests/asyncapi/sqs/test_server.py | 10 + tests/asyncapi/test_app_info.py | 59 ++++++ tests/brokers/base/rpc.py | 22 ++ tests/brokers/kafka/test_connect.py | 2 +- tests/brokers/nats/test_connect.py | 2 +- tests/brokers/rabbit/test_connect.py | 2 +- tests/brokers/redis/test_connect.py | 2 +- tests/brokers/sqs/test_connect.py | 2 +- tests/cli/conftest.py | 69 ++++--- tests/cli/test_doc.py | 59 ++++++ tests/cli/test_run.py | 151 +++++++++----- tests/cli/utils/test_imports.py | 8 - tests/tools/__init__.py | 0 tests/tools/marks.py | 13 ++ 75 files changed, 1681 insertions(+), 274 deletions(-) create mode 100644 propan/asyncapi/bindings/kafka.py create mode 100644 propan/asyncapi/bindings/nats.py create mode 100644 propan/asyncapi/bindings/redis.py create mode 100644 propan/asyncapi/bindings/sqs.py create mode 100644 tests/asyncapi/__init__.py create mode 100644 tests/asyncapi/handler/__init__.py create mode 100644 tests/asyncapi/handler/test_base_arguments.py create mode 100644 tests/asyncapi/handler/test_dependencies_arguments.py create mode 100644 tests/asyncapi/kafka/__init__.py create mode 100644 tests/asyncapi/kafka/test_handler.py create mode 100644 tests/asyncapi/kafka/test_server.py create mode 100644 tests/asyncapi/nats/__init__.py create mode 100644 tests/asyncapi/nats/test_handler.py create mode 100644 tests/asyncapi/nats/test_server.py create mode 100644 tests/asyncapi/rabbit/__init__.py create mode 100644 tests/asyncapi/rabbit/test_handler.py create mode 100644 tests/asyncapi/rabbit/test_server.py create mode 100644 tests/asyncapi/redis/__init__.py create mode 100644 tests/asyncapi/redis/test_handler.py create mode 100644 tests/asyncapi/redis/test_server.py create mode 100644 tests/asyncapi/sqs/__init__.py create mode 100644 tests/asyncapi/sqs/test_handler.py create mode 100644 tests/asyncapi/sqs/test_server.py create mode 100644 tests/asyncapi/test_app_info.py create mode 100644 tests/cli/test_doc.py create mode 100644 tests/tools/__init__.py create mode 100644 tests/tools/marks.py diff --git a/docs/docs/ru/index.md b/docs/docs/ru/index.md index 0bc62c69..86cadbf2 100644 --- a/docs/docs/ru/index.md +++ b/docs/docs/ru/index.md @@ -41,7 +41,7 @@ * [**Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ зависимостями**](getting_started/1_quick-start/#_4): Π­Ρ„Ρ„Π΅ΠΊΡ‚ΠΈΠ²Π½ΠΎΠ΅ ΠΏΠ΅Ρ€Π΅ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ Π·Π° счСт Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ Ρ‚ΠΈΠΏΠΎΠ². Доступ ΠΊ зависимостями Π²ΠΎ всСм стСкС Π²Ρ‹Π·ΠΎΠ²Π°. * [**Π˜Π½Ρ‚eграция**](getting_started/1_quick-start/#http): Propan ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ совмСстим с [Π»ΡŽΠ±Ρ‹ΠΌΠΈ HTTP Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠ°ΠΌΠΈ](integrations/1_integrations-index/) * **ΠΠ΅Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΡŒ ΠΎΡ‚ Π±Ρ€ΠΎΠΊΠ΅Ρ€ΠΎΠ²**: Π•Π΄ΠΈΠ½Ρ‹ΠΉ интСрфСйс для популярных Π±Ρ€ΠΎΠΊΠ΅Ρ€ΠΎΠ²: - * **Redis** (основан Π½Π° [redis-py]("{{ urls.redis }}"){target="_blank"}) + * **Redis** (основан Π½Π° [redis-py]({{ urls.redis }}){target="_blank"}) * **RabbitMQ** (основан Π½Π° [aio-pika]({{ urls.aio_pika }}){target="_blank"}) * **Kafka** (основан Π½Π° [aiokafka]({{ urls.aiokafka }}){target="_blank"}) * **SQS** (основан Π½Π° [aiobotocore]({{ urls.aiobotocore }}){target="_blank"}) diff --git a/propan/asyncapi/__init__.py b/propan/asyncapi/__init__.py index 858af50f..cff29e20 100644 --- a/propan/asyncapi/__init__.py +++ b/propan/asyncapi/__init__.py @@ -1,7 +1,9 @@ from propan.asyncapi.bindings import AsyncAPIChannelBinding from propan.asyncapi.channels import AsyncAPIChannel from propan.asyncapi.info import AsyncAPIContact, AsyncAPIInfo, AsyncAPILicense -from propan.asyncapi.main import ASYNC_API_VERSION, AsyncAPISchema +from propan.asyncapi.main import ASYNC_API_VERSION, AsyncAPIComponents, AsyncAPISchema +from propan.asyncapi.message import AsyncAPIMessage +from propan.asyncapi.security import AsyncAPISecuritySchemeComponent from propan.asyncapi.servers import AsyncAPIServer from propan.asyncapi.utils import AsyncAPIExternalDocs, AsyncAPITag @@ -9,6 +11,7 @@ # main "ASYNC_API_VERSION", "AsyncAPISchema", + "AsyncAPIComponents", # info "AsyncAPIInfo", "AsyncAPIContact", @@ -22,4 +25,8 @@ "AsyncAPIExternalDocs", # bindings "AsyncAPIChannelBinding", + # messages + "AsyncAPIMessage", + # security + "AsyncAPISecuritySchemeComponent", ) diff --git a/propan/asyncapi/bindings/amqp.py b/propan/asyncapi/bindings/amqp.py index fe33eb37..8ea90340 100644 --- a/propan/asyncapi/bindings/amqp.py +++ b/propan/asyncapi/bindings/amqp.py @@ -33,8 +33,8 @@ class Config: class AsyncAPIAmqpChannelBinding(BaseModel): is_: Literal["queue", "routingKey"] = Field(..., alias="is") - version: Optional[str] = Field( - default=None, + version: str = Field( + default="0.2.0", alias="bindingVersion", ) queue: Optional[AsyncAPIAmqpQueue] = None @@ -48,6 +48,10 @@ class AsyncAPIAmqpOperationBinding(BaseModel): cc: Optional[str] = None ack: bool = True reply_to: Optional[AnyDict] = Field(default=None, alias="replyTo") + version: str = Field( + default="0.2.0", + alias="bindingVersion", + ) class Config: allow_population_by_field_name = True diff --git a/propan/asyncapi/bindings/kafka.py b/propan/asyncapi/bindings/kafka.py new file mode 100644 index 00000000..b6ff2f98 --- /dev/null +++ b/propan/asyncapi/bindings/kafka.py @@ -0,0 +1,41 @@ +from typing import List, Optional + +from pydantic import BaseModel, Field + +from propan.types import AnyDict + + +class AsyncAPIKafkaChannelBinding(BaseModel): + topic: List[str] + partitions: Optional[int] = None + replicas: Optional[int] = None + # TODO: + # topicConfiguration + version: str = Field( + default="0.4.0", + alias="bindingVersion", + ) + + class Config: + allow_population_by_field_name = True + + +class AsyncAPIKafkaOperationBinding(BaseModel): + group_id: Optional[AnyDict] = Field( + default=None, + alias="groupId", + ) + client_id: Optional[AnyDict] = Field( + default=None, + alias="clientId", + ) + + reply_to: Optional[AnyDict] = Field(default=None, alias="replyTo") + + version: str = Field( + default="0.4.0", + alias="bindingVersion", + ) + + class Config: + allow_population_by_field_name = True diff --git a/propan/asyncapi/bindings/main.py b/propan/asyncapi/bindings/main.py index 7ed5cbcd..577c90d0 100644 --- a/propan/asyncapi/bindings/main.py +++ b/propan/asyncapi/bindings/main.py @@ -6,11 +6,35 @@ AsyncAPIAmqpChannelBinding, AsyncAPIAmqpOperationBinding, ) +from propan.asyncapi.bindings.kafka import ( + AsyncAPIKafkaChannelBinding, + AsyncAPIKafkaOperationBinding, +) +from propan.asyncapi.bindings.nats import ( + AsyncAPINatsChannelBinding, + AsyncAPINatsOperationBinding, +) +from propan.asyncapi.bindings.redis import ( + AsyncAPIRedisChannelBinding, + AsyncAPIRedisOperationBinding, +) +from propan.asyncapi.bindings.sqs import ( + AsyncAPISQSChannelBinding, + AsyncAPISQSOperationBinding, +) class AsyncAPIChannelBinding(BaseModel): amqp: Optional[AsyncAPIAmqpChannelBinding] = None + kafka: Optional[AsyncAPIKafkaChannelBinding] = None + sqs: Optional[AsyncAPISQSChannelBinding] = None + nats: Optional[AsyncAPINatsChannelBinding] = None + redis: Optional[AsyncAPIRedisChannelBinding] = None class AsyncAPIOperationBinding(BaseModel): amqp: Optional[AsyncAPIAmqpOperationBinding] = None + kafka: Optional[AsyncAPIKafkaOperationBinding] = None + sqs: Optional[AsyncAPISQSOperationBinding] = None + nats: Optional[AsyncAPINatsOperationBinding] = None + redis: Optional[AsyncAPIRedisOperationBinding] = None diff --git a/propan/asyncapi/bindings/nats.py b/propan/asyncapi/bindings/nats.py new file mode 100644 index 00000000..5a57e54a --- /dev/null +++ b/propan/asyncapi/bindings/nats.py @@ -0,0 +1,28 @@ +from typing import Optional + +from pydantic import BaseModel, Field + +from propan.types import AnyDict + + +class AsyncAPINatsChannelBinding(BaseModel): + subject: str + queue: Optional[str] = None + version: str = Field( + default="custom", + alias="bindingVersion", + ) + + class Config: + allow_population_by_field_name = True + + +class AsyncAPINatsOperationBinding(BaseModel): + reply_to: Optional[AnyDict] = Field(default=None, alias="replyTo") + version: str = Field( + default="custom", + alias="bindingVersion", + ) + + class Config: + allow_population_by_field_name = True diff --git a/propan/asyncapi/bindings/redis.py b/propan/asyncapi/bindings/redis.py new file mode 100644 index 00000000..41e5c39f --- /dev/null +++ b/propan/asyncapi/bindings/redis.py @@ -0,0 +1,29 @@ +from typing import Optional + +from pydantic import BaseModel, Field +from typing_extensions import Literal + +from propan.types import AnyDict + + +class AsyncAPIRedisChannelBinding(BaseModel): + channel: str + method: Literal["ssubscribe", "psubscribe", "subscribe"] = "subscribe" + version: str = Field( + default="custom", + alias="bindingVersion", + ) + + class Config: + allow_population_by_field_name = True + + +class AsyncAPIRedisOperationBinding(BaseModel): + reply_to: Optional[AnyDict] = Field(default=None, alias="replyTo") + version: str = Field( + default="custom", + alias="bindingVersion", + ) + + class Config: + allow_population_by_field_name = True diff --git a/propan/asyncapi/bindings/sqs.py b/propan/asyncapi/bindings/sqs.py new file mode 100644 index 00000000..cdd51a5c --- /dev/null +++ b/propan/asyncapi/bindings/sqs.py @@ -0,0 +1,28 @@ +from typing import Optional + +from pydantic import BaseModel, Field + +from propan.types import AnyDict + + +class AsyncAPISQSChannelBinding(BaseModel): + queue: AnyDict + version: str = Field( + default="custom", + alias="bindingVersion", + ) + + class Config: + allow_population_by_field_name = True + + +class AsyncAPISQSOperationBinding(BaseModel): + reply_to: Optional[AnyDict] = Field(default=None, alias="replyTo") + + version: str = Field( + default="custom", + alias="bindingVersion", + ) + + class Config: + allow_population_by_field_name = True diff --git a/propan/asyncapi/channels.py b/propan/asyncapi/channels.py index f4b048a8..7d1d1c55 100644 --- a/propan/asyncapi/channels.py +++ b/propan/asyncapi/channels.py @@ -11,6 +11,7 @@ class AsyncAPIPublish(BaseModel): class AsyncAPIChannelParameters(BaseModel): + # TODO ... diff --git a/propan/asyncapi/main.py b/propan/asyncapi/main.py index 4dd22862..c88f644f 100644 --- a/propan/asyncapi/main.py +++ b/propan/asyncapi/main.py @@ -4,13 +4,36 @@ from propan.asyncapi.channels import AsyncAPIChannel from propan.asyncapi.info import AsyncAPIInfo +from propan.asyncapi.message import AsyncAPIMessage from propan.asyncapi.servers import AsyncAPIServer from propan.asyncapi.utils import AsyncAPIExternalDocs, AsyncAPITag from propan.brokers._model.schemas import ContentTypes +from propan.types import AnyDict ASYNC_API_VERSION = "2.6.0" +class AsyncAPIComponents(BaseModel): + # TODO + # servers + # serverVariavles + # channels + messages: Optional[Dict[str, AsyncAPIMessage]] = None + schemas: Optional[Dict[str, AnyDict]] = None + + # securitySchemes + # parameters + # correlationIds + # operationTraits + # messageTraits + # serverBindings + # channelBindings + # operationBindings + # messageBindings + class Config: + allow_population_by_field_name = True + + class AsyncAPISchema(BaseModel): asyncapi: str = ASYNC_API_VERSION default_content_type: str = Field( @@ -28,7 +51,7 @@ class AsyncAPISchema(BaseModel): # TODO: # id - # components + components: Optional[AsyncAPIComponents] = None class Config: allow_population_by_field_name = True diff --git a/propan/asyncapi/message.py b/propan/asyncapi/message.py index b00144d5..cb40908a 100644 --- a/propan/asyncapi/message.py +++ b/propan/asyncapi/message.py @@ -29,6 +29,7 @@ class AsyncAPIMessage(BaseModel): ) payload: Dict[str, Any] + # TODO: # headers # schemaFormat # bindings diff --git a/propan/asyncapi/servers.py b/propan/asyncapi/servers.py index f18e3d3f..9842750d 100644 --- a/propan/asyncapi/servers.py +++ b/propan/asyncapi/servers.py @@ -8,7 +8,7 @@ class AsyncAPIServer(BaseModel): url: str protocol: str - description: str = "" + description: Optional[str] = None protocol_version: Optional[str] = Field( default=None, alias="protocolVersion", diff --git a/propan/asyncapi/utils.py b/propan/asyncapi/utils.py index e9b5531e..9596352c 100644 --- a/propan/asyncapi/utils.py +++ b/propan/asyncapi/utils.py @@ -1,4 +1,5 @@ import json +import sys from typing import Optional, Type from pydantic import BaseModel, Field @@ -22,24 +23,27 @@ class Config: def add_example_to_model(model: Type[BaseModel]) -> Type[BaseModel]: - from polyfactory.factories.pydantic_factory import ( - ModelFactory, - ) # mv it to hide from main dependencies - - factory = type(f"{model.__name__}_factory", (ModelFactory,), {"__model__": model}) - - return type( - model.__name__, - (model,), - { - "Config": type( - "Config", - (model.Config,), - { - "schema_extra": { - "example": json.loads(factory.build().json()), + if sys.version_info >= (3, 8): + from polyfactory.factories.pydantic_factory import ModelFactory + + factory = type( + f"{model.__name__}_factory", (ModelFactory,), {"__model__": model} + ) + + return type( + model.__name__, + (model,), + { + "Config": type( + "Config", + (model.Config,), + { + "schema_extra": { + "example": json.loads(factory.build().json()), + }, }, - }, - ) - }, - ) + ) + }, + ) + else: # pragma: no cover + return model diff --git a/propan/brokers/_model/broker_usecase.py b/propan/brokers/_model/broker_usecase.py index 9f469bb3..b3c6c7f2 100644 --- a/propan/brokers/_model/broker_usecase.py +++ b/propan/brokers/_model/broker_usecase.py @@ -2,6 +2,7 @@ import logging from abc import ABC, abstractmethod from functools import wraps +from itertools import chain from typing import ( Any, Awaitable, @@ -17,9 +18,8 @@ ) from fast_depends.construct import get_dependant -from fast_depends.model import Dependant +from fast_depends.model import Dependant, Depends from fast_depends.utils import args_to_kwargs -from pydantic.fields import ModelField from typing_extensions import Self from propan.brokers._model.schemas import ( @@ -48,7 +48,7 @@ Wrapper, ) from propan.utils import apply_types, context -from propan.utils.functions import get_function_arguments, to_async +from propan.utils.functions import get_function_positional_arguments, to_async T = TypeVar("T") @@ -57,6 +57,7 @@ class BrokerUsecase(ABC): logger: Optional[logging.Logger] log_level: int handlers: Sequence[BaseHandler] + dependencies: Sequence[Depends] _connection: Any _fmt: Optional[str] @@ -67,8 +68,10 @@ def __init__( logger: Optional[logging.Logger] = access_logger, log_level: int = logging.INFO, log_fmt: Optional[str] = "%(asctime)s %(levelname)s - %(message)s", + dependencies: Sequence[Depends] = (), # AsyncAPI protocol: str = "", + protocol_version: Optional[str] = None, url_: Union[str, List[str]] = "", **kwargs: Any, ) -> None: @@ -79,6 +82,7 @@ def __init__( self._connection = None self._is_apply_types = apply_types self.handlers = [] + self.dependencies = dependencies self._connection_args = args self._connection_kwargs = kwargs @@ -87,11 +91,12 @@ def __init__( context.set_global("broker", self) self.protocol = protocol + self.protocol_version = protocol_version self.url = url_ async def connect(self, *args: Any, **kwargs: Any) -> Any: if self._connection is None: - arguments = get_function_arguments(self.__init__) # type: ignore + arguments = get_function_positional_arguments(self.__init__) # type: ignore init_kwargs = args_to_kwargs( arguments, *self._connection_args, @@ -148,6 +153,7 @@ def _get_log_context( def handle( self, *broker_args: Any, + dependencies: Sequence[Depends] = (), retry: Union[bool, int] = False, _raw: bool = False, **broker_kwargs: Any, @@ -191,19 +197,28 @@ def _wrap_handler( func: AnyCallable, retry: Union[bool, int] = False, _raw: bool = False, + extra_dependencies: Sequence[Depends] = (), **broker_args: Any, - ) -> DecoratedAsync: + ) -> Tuple[DecoratedAsync, Dependant]: dependant: Dependant = get_dependant(path="", call=func) + extra: List[Dependant] = [ + get_dependant(path="", call=d.dependency) + for d in chain(extra_dependencies, self.dependencies) + ] + dependant.dependencies.extend(extra) f = to_async(func) if self._is_apply_types is True: - f = apply_types(f) + f = apply_types( + func=f, + wrap_dependant=extend_dependencies(extra), + ) f = self._wrap_decode_message( f, _raw=_raw, - params=dependant.real_params, + params=tuple(chain(dependant.flat_params, extra)), ) if self.logger is not None: @@ -217,12 +232,12 @@ def _wrap_handler( f = suppress_decor(f) - return f + return f, dependant def _wrap_decode_message( self, func: Callable[..., Awaitable[T]], - params: Sequence[ModelField] = (), + params: Sequence[Any] = (), _raw: bool = False, ) -> Callable[[PropanMessage], Awaitable[T]]: decode: Callable[ @@ -298,3 +313,11 @@ def _log( async def _fake_decode(message: PropanMessage) -> PropanMessage: return message + + +def extend_dependencies(extra: Sequence[Dependant]) -> Callable[[Dependant], Dependant]: + def dependant_wrapper(dependant: Dependant) -> Dependant: + dependant.dependencies.extend(extra) + return dependant + + return dependant_wrapper diff --git a/propan/brokers/_model/schemas.py b/propan/brokers/_model/schemas.py index ebc22fc4..cfc781b5 100644 --- a/propan/brokers/_model/schemas.py +++ b/propan/brokers/_model/schemas.py @@ -5,7 +5,7 @@ from typing import Any, Dict, Optional, Sequence, Tuple, Union from uuid import uuid4 -from fast_depends.construct import get_dependant +from fast_depends.model import Dependant from pydantic import BaseModel, Field, Json, create_model from pydantic.dataclasses import dataclass as pydantic_dataclass from typing_extensions import TypeAlias, assert_never @@ -20,7 +20,8 @@ @dataclass class BaseHandler: callback: DecoratedCallable - description: str = field(default="", kw_only=True) # type: ignore + dependant: Dependant + _description: str = field(default="", kw_only=True) # type: ignore @abstractmethod def get_schema(self) -> Dict[str, AsyncAPIChannel]: @@ -30,16 +31,21 @@ def get_schema(self) -> Dict[str, AsyncAPIChannel]: def title(self) -> str: return self.callback.__name__.replace("_", " ").title().replace(" ", "") + @property + def description(self) -> Optional[str]: + return self._description or self.callback.__doc__ + def get_message_object(self) -> Tuple[str, AnyDict, Optional[AnyDict]]: import jsonref # hide it there to remove docs dependencies from main package - dependant = get_dependant(path="", call=self.callback) + + dependant = self.dependant if dependant.return_field: return_field = dependant.return_field if issubclass(return_field.type_, BaseModel): return_model = return_field.type_ - if return_model.Config.schema_extra.get("example") is None: + if not return_model.Config.schema_extra.get("example"): return_model = add_example_to_model(return_model) return_info = jsonref.replace_refs( return_model.schema(), jsonschema=True, proxies=False @@ -47,7 +53,7 @@ def get_message_object(self) -> Tuple[str, AnyDict, Optional[AnyDict]]: return_info["examples"] = [return_info.pop("example")] else: - return_model = create_model( + return_model = create_model( # type: ignore f"{self.title}Reply", **{return_field.name: (return_field.annotation, ...)}, ) @@ -70,12 +76,12 @@ def get_message_object(self) -> Tuple[str, AnyDict, Optional[AnyDict]]: else: return_info = None - # TODO: test recursive schema generation - schema_title = f"{self.title}Message" + payload_title = f"{self.title}Payload" params = dependant.flat_params params_number = len(params) gen_examples: bool + use_original_model = False if params_number == 0: model = None @@ -85,10 +91,11 @@ def get_message_object(self) -> Tuple[str, AnyDict, Optional[AnyDict]]: if issubclass(param.annotation, BaseModel): model = param.annotation gen_examples = model.Config.schema_extra.get("example") is None + use_original_model = True else: - model = create_model( - schema_title, + model = create_model( # type: ignore + payload_title, **{ param.name: ( param.annotation, @@ -100,7 +107,7 @@ def get_message_object(self) -> Tuple[str, AnyDict, Optional[AnyDict]]: else: model = create_model( # type: ignore - schema_title, + payload_title, **{ p.name: (p.annotation, ... if p.required else p.default) for p in params @@ -108,16 +115,32 @@ def get_message_object(self) -> Tuple[str, AnyDict, Optional[AnyDict]]: ) gen_examples = True + body: AnyDict if model is None: - body = {"title": schema_title, "type": "null"} + body = {"title": payload_title, "type": "null"} else: if gen_examples is True: model = add_example_to_model(model) body = jsonref.replace_refs(model.schema(), jsonschema=True, proxies=False) body.pop("definitions", None) - return_info.pop("definitions", None) - return body.get("title", schema_title), body, return_info + if return_info is not None: + return_info.pop("definitions", None) + + if params_number == 1 and not use_original_model: + param_body: AnyDict = body.get("properties", {}) + key = list(param_body.keys())[0] + param_body = param_body[key] + param_body.update( + { + "example": body.get("example", {}).get(key), + "title": body.get("title", param_body.get("title")), + } + ) + param_body["example"] = body.get("example", {}).get(key) + body = param_body + + return f"{self.title}Message", body, return_info class ContentTypes(str, Enum): diff --git a/propan/brokers/kafka/kafka_broker.py b/propan/brokers/kafka/kafka_broker.py index bd71ad70..7d6ab206 100644 --- a/propan/brokers/kafka/kafka_broker.py +++ b/propan/brokers/kafka/kafka_broker.py @@ -6,6 +6,7 @@ from aiokafka import AIOKafkaConsumer, AIOKafkaProducer from aiokafka.structs import ConsumerRecord +from fast_depends.model import Depends from typing_extensions import TypeAlias, TypeVar from propan.__about__ import __version__ @@ -42,12 +43,16 @@ def __init__( *, response_topic: str = "", log_fmt: Optional[str] = None, + protocol: str = "kafka", + api_version: str = "auto", **kwargs: AnyDict, ) -> None: super().__init__( bootstrap_servers, log_fmt=log_fmt, url_=bootstrap_servers, + protocol=protocol, + protocol_version=api_version, **kwargs, ) self.__max_topic_len = 4 @@ -112,17 +117,27 @@ def handle( self, *topics: str, _raw: bool = False, + dependencies: Sequence[Depends] = (), + description: str = "", + group_id: Optional[str] = None, **kwargs: AnyDict, ) -> Wrapper: def wrapper(func: AnyCallable) -> DecoratedCallable: for t in topics: self.__max_topic_len = max((self.__max_topic_len, len(t))) - func = self._wrap_handler(func, _raw=_raw) + func, dependant = self._wrap_handler( + func, + _raw=_raw, + extra_dependencies=dependencies, + ) handler = Handler( callback=func, topics=topics, + _description=description, + group_id=group_id, consumer_kwargs=kwargs, + dependant=dependant, ) self.handlers.append(handler) @@ -149,7 +164,11 @@ async def start(self) -> None: c = self._get_log_context(None, handler.topics) self._log(f"`{handler.callback.__name__}` waiting for messages", extra=c) - consumer = self._connection(*handler.topics, **handler.consumer_kwargs) + consumer = self._connection( + *handler.topics, + group_id=handler.group_id, + **handler.consumer_kwargs, + ) await consumer.start() handler.consumer = consumer handler.task = asyncio.create_task(self._consume(handler)) @@ -278,12 +297,22 @@ def _get_log_context( async def _consume(self, handler: Handler) -> NoReturn: c = self._get_log_context(None, handler.topics) + connected = True while True: try: msg = await handler.consumer.getone() + except Exception as e: - self._log(e, logging.WATNING, c) + if connected is True: + self._log(e, logging.WATNING, c) + connected = False + await asyncio.sleep(5) + else: + if connected is False: + self._log("Connection established", logging.INFO, c) + connected = True + await handler.callback(msg) async def _consume_response(self, message: PropanMessage): diff --git a/propan/brokers/kafka/kafka_broker.pyi b/propan/brokers/kafka/kafka_broker.pyi index 4068aa44..300921b6 100644 --- a/propan/brokers/kafka/kafka_broker.pyi +++ b/propan/brokers/kafka/kafka_broker.pyi @@ -7,6 +7,7 @@ from aiokafka import AIOKafkaConsumer, AIOKafkaProducer from aiokafka.abc import AbstractTokenProvider from aiokafka.producer.producer import _missing from aiokafka.structs import ConsumerRecord +from fast_depends.model import Depends from kafka.coordinator.assignors.abstract import AbstractPartitionAssignor from kafka.coordinator.assignors.roundrobin import RoundRobinPartitionAssignor from kafka.partitioner.default import DefaultPartitioner @@ -83,6 +84,8 @@ class KafkaBroker(BrokerUsecase): log_level: int = logging.INFO, log_fmt: Optional[str] = None, apply_types: bool = True, + dependencies: Sequence[Depends] = (), + protocol: str = "kafka", ) -> None: ... async def connect( self, @@ -165,6 +168,8 @@ class KafkaBroker(BrokerUsecase): "read_committed", ] = "read_uncommitted", retry: Union[bool, int] = False, + dependencies: Sequence[Depends] = (), + description: str = "", ) -> Wrapper: ... async def start(self) -> None: ... @staticmethod diff --git a/propan/brokers/kafka/schemas.py b/propan/brokers/kafka/schemas.py index 3ba1c215..31149e35 100644 --- a/propan/brokers/kafka/schemas.py +++ b/propan/brokers/kafka/schemas.py @@ -1,9 +1,17 @@ import asyncio from dataclasses import dataclass, field -from typing import Any, List, Optional +from typing import Any, Dict, List, Optional from aiokafka import AIOKafkaConsumer +from propan.asyncapi.bindings import ( + AsyncAPIChannelBinding, + AsyncAPIOperationBinding, + kafka, +) +from propan.asyncapi.channels import AsyncAPIChannel +from propan.asyncapi.message import AsyncAPICorrelationId, AsyncAPIMessage +from propan.asyncapi.subscription import AsyncAPISubscription from propan.brokers._model.schemas import BaseHandler from propan.types import AnyDict @@ -11,7 +19,47 @@ @dataclass class Handler(BaseHandler): topics: List[str] + group_id: Optional[str] = None consumer: Optional[AIOKafkaConsumer] = None task: Optional["asyncio.Task[Any]"] = None consumer_kwargs: AnyDict = field(default_factory=dict) + + def get_schema(self) -> Dict[str, AsyncAPIChannel]: + message_title, body, reply_to = self.get_message_object() + + if reply_to: + kafka_kwargs = {"replyTo": reply_to} + else: + kafka_kwargs = {} + + if self.group_id is not None: + kafka_kwargs["groupId"] = {"type": "string", "enum": [self.group_id]} + + if kafka_kwargs: + operation_binding = AsyncAPIOperationBinding( + kafka=kafka.AsyncAPIKafkaOperationBinding(**kafka_kwargs) # type: ignore + ) + else: + operation_binding = None + + return { + self.title: AsyncAPIChannel( + subscribe=AsyncAPISubscription( + description=self.description, + bindings=operation_binding, + message=AsyncAPIMessage( + title=message_title, + payload=body, + correlationId=AsyncAPICorrelationId( + location="$message.header#/correlation_id" + ), + ), + ), + bindings=AsyncAPIChannelBinding( + kafka=kafka.AsyncAPIKafkaChannelBinding( + topic=self.topics, + ) + ), + ), + } diff --git a/propan/brokers/nats/nats_broker.py b/propan/brokers/nats/nats_broker.py index e26f48fe..2eb26f54 100644 --- a/propan/brokers/nats/nats_broker.py +++ b/propan/brokers/nats/nats_broker.py @@ -5,6 +5,7 @@ from typing import Any, Callable, Dict, List, Optional, Sequence, TypeVar, Union import nats +from fast_depends.model import Depends from nats.aio.client import Callback, Client, ErrorCallback from nats.aio.msg import Msg @@ -28,27 +29,15 @@ class NatsBroker(BrokerUsecase): def __init__( self, -<<<<<<< HEAD - servers: Union[str, Sequence[str]] = ("nats://localhost:4222",), - *args: Any, - log_fmt: Optional[str] = None, - **kwargs: AnyDict, - ): - super().__init__( - servers, - *args, - log_fmt=log_fmt, - url_=servers, - **kwargs, - ) -======= servers: Union[str, List[str]] = ["nats://localhost:4222"], # noqa: B006 *, log_fmt: Optional[str] = None, + protocol: str = "nats", **kwargs: AnyDict, ) -> None: - super().__init__(servers, log_fmt=log_fmt, **kwargs) ->>>>>>> ffe6421e3859303b0ecb0c74654b5b53e06e576b + super().__init__( + servers, log_fmt=log_fmt, url_=servers, protocol=protocol, **kwargs + ) self._connection = None @@ -78,20 +67,29 @@ def handle( queue: str = "", *, retry: Union[bool, int] = False, + dependencies: Sequence[Depends] = (), _raw: bool = False, + description: str = "", ) -> Callable[[DecoratedCallable], None]: self.__max_subject_len = max((self.__max_subject_len, len(subject))) self.__max_queue_len = max((self.__max_queue_len, len(queue))) def wrapper(func: DecoratedCallable) -> None: - func = self._wrap_handler( + func, dependant = self._wrap_handler( func, queue=queue, subject=subject, + extra_dependencies=dependencies, retry=retry, _raw=_raw, ) - handler = Handler(callback=func, subject=subject, queue=queue) + handler = Handler( + callback=func, + subject=subject, + queue=queue, + _description=description, + dependant=dependant, + ) self.handlers.append(handler) return func diff --git a/propan/brokers/nats/nats_broker.pyi b/propan/brokers/nats/nats_broker.pyi index 318e0c08..7e5cce98 100644 --- a/propan/brokers/nats/nats_broker.pyi +++ b/propan/brokers/nats/nats_broker.pyi @@ -1,7 +1,8 @@ import logging import ssl -from typing import Any, Callable, Dict, List, Optional, TypeVar, Union +from typing import Any, Callable, Dict, List, Optional, Sequence, TypeVar, Union +from fast_depends.model import Depends from nats.aio.client import ( DEFAULT_CONNECT_TIMEOUT, DEFAULT_DRAIN_TIMEOUT, @@ -73,6 +74,8 @@ class NatsBroker(BrokerUsecase): log_level: int = logging.INFO, log_fmt: Optional[str] = None, apply_types: bool = True, + dependencies: Sequence[Depends] = (), + protocol: str = "nats", ) -> None: ... async def connect( self, @@ -126,6 +129,8 @@ class NatsBroker(BrokerUsecase): queue: str = "", *, retry: Union[bool, int] = False, + dependencies: Sequence[Depends] = (), + description: str = "", ) -> HandlerWrapper: ... async def _connect(self, *args: Any, **kwargs: Any) -> Client: ... async def close(self) -> None: ... diff --git a/propan/brokers/nats/schemas.py b/propan/brokers/nats/schemas.py index 3c3441e6..71175080 100644 --- a/propan/brokers/nats/schemas.py +++ b/propan/brokers/nats/schemas.py @@ -1,10 +1,18 @@ from dataclasses import dataclass -from typing import Optional, Sequence +from typing import Dict, Optional, Sequence from nats.aio.subscription import Subscription from nats.js.api import DEFAULT_PREFIX from pydantic import BaseModel +from propan.asyncapi.bindings import ( + AsyncAPIChannelBinding, + AsyncAPIOperationBinding, + nats, +) +from propan.asyncapi.channels import AsyncAPIChannel +from propan.asyncapi.message import AsyncAPIMessage +from propan.asyncapi.subscription import AsyncAPISubscription from propan.brokers._model.schemas import BaseHandler @@ -15,6 +23,32 @@ class Handler(BaseHandler): subscription: Optional[Subscription] = None + def get_schema(self) -> Dict[str, AsyncAPIChannel]: + message_title, body, reply_to = self.get_message_object() + + return { + self.title: AsyncAPIChannel( + subscribe=AsyncAPISubscription( + description=self.description, + bindings=AsyncAPIOperationBinding( + nats=nats.AsyncAPINatsOperationBinding( + replyTo=reply_to, + ), + ), + message=AsyncAPIMessage( + title=message_title, + payload=body, + ), + ), + bindings=AsyncAPIChannelBinding( + nats=nats.AsyncAPINatsChannelBinding( + subject=self.subject, + queue=self.queue or None, + ) + ), + ), + } + class JetStream(BaseModel): prefix: str = DEFAULT_PREFIX diff --git a/propan/brokers/push_back_watcher.py b/propan/brokers/push_back_watcher.py index f65bdf90..b5021a26 100644 --- a/propan/brokers/push_back_watcher.py +++ b/propan/brokers/push_back_watcher.py @@ -112,7 +112,7 @@ async def __aexit__( await call_or_await(self.on_success) self.watcher.remove(self._message_id) - elif isinstance(exc_val, SkipMessage) is True: + elif isinstance(exc_val, SkipMessage): self.watcher.remove(self._message_id) elif self.watcher.is_max(self._message_id): diff --git a/propan/brokers/rabbit/rabbit_broker.py b/propan/brokers/rabbit/rabbit_broker.py index 928f2044..15bf0edf 100644 --- a/propan/brokers/rabbit/rabbit_broker.py +++ b/propan/brokers/rabbit/rabbit_broker.py @@ -1,11 +1,12 @@ import asyncio from functools import wraps -from typing import Any, Callable, Dict, List, Optional, Type, TypeVar, Union +from typing import Any, Callable, Dict, List, Optional, Sequence, Type, TypeVar, Union from uuid import uuid4 import aio_pika import aiormq from aio_pika.abc import DeliveryMode +from fast_depends.model import Depends from yarl import URL from propan.brokers._model import BrokerUsecase @@ -33,31 +34,22 @@ class RabbitBroker(BrokerUsecase): def __init__( self, -<<<<<<< HEAD - url: Optional[str] = None, - *args: Tuple[Any, ...], - protocol: str = "amqp", - consumers: Optional[int] = None, -======= url: Union[str, URL, None] = None, *, ->>>>>>> ffe6421e3859303b0ecb0c74654b5b53e06e576b log_fmt: Optional[str] = None, consumers: Optional[int] = None, + protocol: str = "amqp", + protocol_version: str = "0.9.1", **kwargs: AnyDict, ) -> None: -<<<<<<< HEAD super().__init__( url, - *args, log_fmt=log_fmt, + url_=url or "amqp://guest:guest@localhost:5672/", protocol=protocol, - url_=url, + protocol_version=protocol_version, **kwargs, ) -======= - super().__init__(url, log_fmt=log_fmt, **kwargs) ->>>>>>> ffe6421e3859303b0ecb0c74654b5b53e06e576b self._max_consumers = consumers self._channel = None @@ -100,18 +92,20 @@ def handle( exchange: Union[str, RabbitExchange, None] = None, *, retry: Union[bool, int] = False, - _raw: bool = False, + dependencies: Sequence[Depends] = (), description: str = "", + _raw: bool = False, ) -> HandlerWrapper: queue, exchange = _validate_queue(queue), _validate_exchange(exchange) self.__setup_log_context(queue, exchange) def wrapper(func: DecoratedCallable) -> Any: - func = self._wrap_handler( + func, dependant = self._wrap_handler( func, queue=queue, exchange=exchange, + extra_dependencies=dependencies, retry=retry, _raw=_raw, ) @@ -119,7 +113,8 @@ def wrapper(func: DecoratedCallable) -> Any: callback=func, queue=queue, exchange=exchange, - description=description, + _description=description, + dependant=dependant, ) self.handlers.append(handler) diff --git a/propan/brokers/rabbit/rabbit_broker.pyi b/propan/brokers/rabbit/rabbit_broker.pyi index 72ae019b..34e839f5 100644 --- a/propan/brokers/rabbit/rabbit_broker.pyi +++ b/propan/brokers/rabbit/rabbit_broker.pyi @@ -1,9 +1,21 @@ import logging from ssl import SSLContext -from typing import Any, Callable, Coroutine, Dict, List, Optional, Type, TypeVar, Union +from typing import ( + Any, + Callable, + Coroutine, + Dict, + List, + Optional, + Sequence, + Type, + TypeVar, + Union, +) import aio_pika import aiormq +from fast_depends.model import Depends from pamqp.common import FieldTable from typing_extensions import ParamSpec from yarl import URL @@ -41,13 +53,16 @@ class RabbitBroker(BrokerUsecase): ssl_context: Optional[SSLContext] = None, timeout: aio_pika.abc.TimeoutType = None, client_properties: Optional[FieldTable] = None, + # broker logger: Optional[logging.Logger] = access_logger, log_level: int = logging.INFO, log_fmt: Optional[str] = None, apply_types: bool = True, consumers: Optional[int] = None, + dependencies: Sequence[Depends] = (), # AsyncAPI protocol: str = "amqp", + protocol_version: str = "0.9.1", ) -> None: """RabbitMQ Propan broker @@ -72,6 +87,7 @@ class RabbitBroker(BrokerUsecase): log_fmt: custom log formatting string apply_types: wrap brokers handlers to FastDepends decorator consumers: max messages to proccess at the same time + dependencies: dependencies applied to all broker hadlers .. _RFC3986: https://goo.gl/MzgYAs .. _official Python documentation: https://goo.gl/pty9xA @@ -187,6 +203,7 @@ class RabbitBroker(BrokerUsecase): exchange: Union[str, RabbitExchange, None] = None, *, retry: Union[bool, int] = False, + dependencies: Sequence[Depends] = (), # AsyncAPI description: str = "", ) -> Callable[ @@ -203,6 +220,7 @@ class RabbitBroker(BrokerUsecase): queue: queue to consume messages exchange: exchange to bind queue retry: at message exception will returns to queue `int` times or endless if `True` + description: AsyncAPI channel object description Returns: Async or sync function decorator diff --git a/propan/brokers/rabbit/schemas.py b/propan/brokers/rabbit/schemas.py index 11ba643b..65f22dc3 100644 --- a/propan/brokers/rabbit/schemas.py +++ b/propan/brokers/rabbit/schemas.py @@ -122,7 +122,7 @@ def get_schema(self) -> Dict[str, AsyncAPIChannel]: return { self.title: AsyncAPIChannel( subscribe=AsyncAPISubscription( - description=self.description or self.callback.__doc__, + description=self.description, bindings=AsyncAPIOperationBinding( amqp=amqp.AsyncAPIAmqpOperationBinding( cc=None @@ -132,34 +132,40 @@ def get_schema(self) -> Dict[str, AsyncAPIChannel]: in (ExchangeType.FANOUT, ExchangeType.HEADERS) ) else self.queue.name, - reply_to=reply_to, + replyTo=reply_to, ), ), message=AsyncAPIMessage( - name=message_title, + title=message_title, payload=body, - correlation_id=AsyncAPICorrelationId( + correlationId=AsyncAPICorrelationId( location="$message.header#/correlation_id" ), ), ), bindings=AsyncAPIChannelBinding( amqp=amqp.AsyncAPIAmqpChannelBinding( - is_="routingKey", - queue=amqp.AsyncAPIAmqpQueue( + is_="routingKey", # type: ignore + queue=None + if ( + self.exchange + and self.exchange.type + in (ExchangeType.FANOUT, ExchangeType.HEADERS) + ) + else amqp.AsyncAPIAmqpQueue( name=self.queue.name, durable=self.queue.durable, exclusive=self.queue.exclusive, - auto_delete=self.queue.auto_delete, + autoDelete=self.queue.auto_delete, ), exchange=( amqp.AsyncAPIAmqpExchange(type="default") if self.exchange is None else amqp.AsyncAPIAmqpExchange( - type=self.exchange.type.value, + type=self.exchange.type.value, # type: ignore name=self.exchange.name, durable=self.exchange.durable, - auto_delete=self.exchange.auto_delete, + autoDelete=self.exchange.auto_delete, ) ), ) diff --git a/propan/brokers/redis/redis_broker.py b/propan/brokers/redis/redis_broker.py index 2b2859a2..956f6f7f 100644 --- a/propan/brokers/redis/redis_broker.py +++ b/propan/brokers/redis/redis_broker.py @@ -1,9 +1,10 @@ import asyncio import logging from functools import wraps -from typing import Any, Callable, Dict, List, NoReturn, Optional, TypeVar +from typing import Any, Callable, Dict, List, NoReturn, Optional, Sequence, TypeVar from uuid import uuid4 +from fast_depends.model import Depends from redis.asyncio.client import PubSub, Redis from redis.asyncio.connection import ConnectionPool, parse_url @@ -35,9 +36,16 @@ def __init__( *, polling_interval: float = 1.0, log_fmt: Optional[str] = None, + protocol: str = "redis", **kwargs: Any, ) -> None: - super().__init__(url=url, log_fmt=log_fmt, **kwargs) + super().__init__( + url, + log_fmt=log_fmt, + url_=url, + protocol=protocol, + **kwargs, + ) self.__max_channel_len = 0 self._polling_interval = polling_interval @@ -88,17 +96,26 @@ def handle( channel: str = "", *, pattern: bool = False, + dependencies: Sequence[Depends] = (), + description: str = "", _raw: bool = False, ) -> HandlerWrapper: self.__max_channel_len = max(self.__max_channel_len, len(channel)) def wrapper(func: AnyCallable) -> DecoratedCallable: - func = self._wrap_handler( + func, dependant = self._wrap_handler( func, channel=channel, + extra_dependencies=dependencies, _raw=_raw, ) - handler = Handler(callback=func, channel=channel, pattern=pattern) + handler = Handler( + callback=func, + channel=channel, + pattern=pattern, + _description=description, + dependant=dependant, + ) self.handlers.append(handler) return func diff --git a/propan/brokers/redis/redis_broker.pyi b/propan/brokers/redis/redis_broker.pyi index 19c04854..c838e6b5 100644 --- a/propan/brokers/redis/redis_broker.pyi +++ b/propan/brokers/redis/redis_broker.pyi @@ -1,6 +1,18 @@ import logging -from typing import Any, Callable, Dict, List, Mapping, Optional, Type, TypeVar, Union - +from typing import ( + Any, + Callable, + Dict, + List, + Mapping, + Optional, + Sequence, + Type, + TypeVar, + Union, +) + +from fast_depends.model import Depends from redis.asyncio.client import Redis from redis.asyncio.connection import BaseParser, Connection, DefaultParser, Encoder @@ -49,6 +61,8 @@ class RedisBroker(BrokerUsecase): log_level: int = logging.INFO, log_fmt: Optional[str] = None, apply_types: bool = True, + dependencies: Sequence[Depends] = (), + protocol: str = "redis", ) -> None: """Redis Pub/sub Propan broker @@ -122,6 +136,8 @@ class RedisBroker(BrokerUsecase): channel: str, *, pattern: bool = False, + dependencies: Sequence[Depends] = (), + description: str = "", ) -> HandlerWrapper: """Register channel consumer method diff --git a/propan/brokers/redis/schemas.py b/propan/brokers/redis/schemas.py index 50c83554..33262bb9 100644 --- a/propan/brokers/redis/schemas.py +++ b/propan/brokers/redis/schemas.py @@ -5,6 +5,14 @@ from pydantic import BaseModel, Field from redis.asyncio.client import PubSub +from propan.asyncapi.bindings import ( + AsyncAPIChannelBinding, + AsyncAPIOperationBinding, + redis, +) +from propan.asyncapi.channels import AsyncAPIChannel +from propan.asyncapi.message import AsyncAPIMessage +from propan.asyncapi.subscription import AsyncAPISubscription from propan.brokers._model.schemas import BaseHandler @@ -16,6 +24,32 @@ class Handler(BaseHandler): task: Optional["asyncio.Task[Any]"] = None subscription: Optional[PubSub] = None + def get_schema(self) -> Dict[str, AsyncAPIChannel]: + message_title, body, reply_to = self.get_message_object() + + return { + self.title: AsyncAPIChannel( + subscribe=AsyncAPISubscription( + description=self.description, + bindings=AsyncAPIOperationBinding( + redis=redis.AsyncAPIRedisOperationBinding( + replyTo=reply_to, + ), + ), + message=AsyncAPIMessage( + title=message_title, + payload=body, + ), + ), + bindings=AsyncAPIChannelBinding( + redis=redis.AsyncAPIRedisChannelBinding( + channel=self.channel, + method="psubscribe" if self.pattern else "subscribe", + ) + ), + ), + } + class RedisMessage(BaseModel): data: bytes diff --git a/propan/brokers/sqs/schema.py b/propan/brokers/sqs/schema.py index d34da571..b6d16807 100644 --- a/propan/brokers/sqs/schema.py +++ b/propan/brokers/sqs/schema.py @@ -6,6 +6,14 @@ from pydantic import BaseModel, Field, PositiveInt from typing_extensions import Literal +from propan.asyncapi.bindings import ( + AsyncAPIChannelBinding, + AsyncAPIOperationBinding, + sqs, +) +from propan.asyncapi.channels import AsyncAPIChannel +from propan.asyncapi.message import AsyncAPICorrelationId, AsyncAPIMessage +from propan.asyncapi.subscription import AsyncAPISubscription from propan.brokers._model import BrokerUsecase from propan.brokers._model.schemas import BaseHandler, Queue from propan.types import SendableMessage @@ -205,6 +213,34 @@ class Handler(BaseHandler): task: Optional["asyncio.Task[Any]"] = None + def get_schema(self) -> Dict[str, AsyncAPIChannel]: + message_title, body, reply_to = self.get_message_object() + + return { + self.title: AsyncAPIChannel( + subscribe=AsyncAPISubscription( + description=self.description, + bindings=AsyncAPIOperationBinding( + sqs=sqs.AsyncAPISQSOperationBinding( + replyTo=reply_to, + ), + ), + message=AsyncAPIMessage( + title=message_title, + correlationId=AsyncAPICorrelationId( + location="$message.header#/correlation_id" + ), + payload=body, + ), + ), + bindings=AsyncAPIChannelBinding( + sqs=sqs.AsyncAPISQSChannelBinding( + queue=self.queue.dict(include={"name", "fifo"}), + ) + ), + ), + } + @dataclass class SQSMessage: diff --git a/propan/brokers/sqs/sqs_broker.py b/propan/brokers/sqs/sqs_broker.py index a934fd98..e382dd4e 100644 --- a/propan/brokers/sqs/sqs_broker.py +++ b/propan/brokers/sqs/sqs_broker.py @@ -16,6 +16,7 @@ from aiobotocore.client import AioBaseClient from aiobotocore.session import get_session +from fast_depends.model import Depends from typing_extensions import TypeAlias from propan.brokers._model import BrokerUsecase @@ -55,9 +56,16 @@ def __init__( *, log_fmt: Optional[str] = None, response_queue: str = "", + protocol: str = "sqs", **kwargs: Any, ) -> None: - super().__init__(url, log_fmt=log_fmt, **kwargs) + super().__init__( + url, + log_fmt=log_fmt, + url_=url, + protocol=protocol, + **kwargs, + ) self._queues = {} self.__max_queue_len = 4 self.response_queue = response_queue @@ -144,6 +152,8 @@ def handle( request_attempt_id: Optional[str] = None, visibility_timeout: int = 0, retry: Union[bool, int] = False, + dependencies: Sequence[Depends] = (), + description: str = "", _raw: bool = False, ) -> HandlerWrapper: if isinstance(queue, str): @@ -167,13 +177,20 @@ def handle( params["ReceiveRequestAttemptId"] = request_attempt_id def wrapper(func: AnyCallable) -> DecoratedCallable: - func = self._wrap_handler( + func, dependant = self._wrap_handler( func, queue=queue.name, retry=retry, + extra_dependencies=dependencies, _raw=_raw, ) - handler = Handler(callback=func, queue=queue, consumer_params=params) + handler = Handler( + callback=func, + queue=queue, + consumer_params=params, + _description=description, + dependant=dependant, + ) self.handlers.append(handler) return func diff --git a/propan/brokers/sqs/sqs_broker.pyi b/propan/brokers/sqs/sqs_broker.pyi index 2a1cf078..c5c87853 100644 --- a/propan/brokers/sqs/sqs_broker.pyi +++ b/propan/brokers/sqs/sqs_broker.pyi @@ -14,6 +14,7 @@ from typing import ( from aiobotocore.client import AioBaseClient from aiobotocore.config import AioConfig +from fast_depends.model import Depends from typing_extensions import TypeAlias from propan.brokers._model import BrokerUsecase @@ -51,6 +52,8 @@ class SQSBroker(BrokerUsecase): log_level: int = logging.INFO, log_fmt: Optional[str] = None, apply_types: bool = True, + dependencies: Sequence[Depends] = (), + protocol: str = "sqs", ) -> None: """""" async def connect( @@ -97,6 +100,8 @@ class SQSBroker(BrokerUsecase): request_attempt_id: Optional[str] = None, visibility_timeout: int = 0, retry: Union[bool, int] = False, + description: str = "", + dependencies: Sequence[Depends] = (), ) -> HandlerWrapper: """""" async def start(self) -> None: diff --git a/propan/cli/app.py b/propan/cli/app.py index 34bbb262..cccd550c 100644 --- a/propan/cli/app.py +++ b/propan/cli/app.py @@ -6,6 +6,7 @@ from anyio.streams.memory import MemoryObjectReceiveStream, MemoryObjectSendStream from typing_extensions import Protocol +from propan.asyncapi.info import AsyncAPIContact, AsyncAPILicense from propan.cli.supervisors.utils import set_exit from propan.cli.utils.parser import SettingField from propan.log import logger @@ -30,6 +31,8 @@ class PropanApp: _stop_stream: Optional[MemoryObjectSendStream[bool]] _receive_stream: Optional[MemoryObjectReceiveStream[bool]] + license: Optional[AsyncAPILicense] + contact: Optional[AsyncAPIContact] def __init__( self, @@ -39,6 +42,8 @@ def __init__( title: str = "Propan", version: str = "0.1.0", description: str = "", + license: Optional[AsyncAPILicense] = None, + contact: Optional[AsyncAPIContact] = None, ): self.broker = broker self.logger = logger @@ -56,6 +61,8 @@ def __init__( self.title = title self.version = version self.description = description + self.license = license + self.contact = contact def set_broker(self, broker: Runnable) -> None: self.broker = broker diff --git a/propan/cli/docs/app.py b/propan/cli/docs/app.py index 075c669f..3fe45eb6 100644 --- a/propan/cli/docs/app.py +++ b/propan/cli/docs/app.py @@ -7,14 +7,14 @@ from propan.cli.docs.serve import serve_docs from propan.cli.utils.imports import get_app_path, try_import_propan - docs_app = typer.Typer(pretty_exceptions_short=True) @docs_app.command(name="gen") def gen( app: str = typer.Argument( - ..., help="[python_module:PropanApp] - path to your application" + ..., + help="[python_module:PropanApp] - path to your application", ), filename: str = typer.Option( "asyncapi.yaml", @@ -40,20 +40,24 @@ def gen( @docs_app.command(name="serve") def serve( app: str = typer.Argument( - ..., help="[python_module:PropanApp] - path to your application" - ), - host: str = typer.Option( - "localhost", help="documentation hosting address" + ..., + help="[python_module:PropanApp] or [asyncapi.yaml] - path to your application documentation", ), - port: int = typer.Option( - 8000, help="documentation hosting port" - ) + host: str = typer.Option("localhost", help="documentation hosting address"), + port: int = typer.Option(8000, help="documentation hosting port"), ) -> None: """Serve project AsyncAPI scheme""" - module, app = get_app_path(app) - app_dir = module.parent - sys.path.insert(0, str(app_dir)) - propan_app = try_import_propan(module, app) + if ":" in app: + module, app = get_app_path(app) + app_dir = module.parent + sys.path.insert(0, str(app_dir)) + propan_app = try_import_propan(module, app) + + schema = get_schema_yaml(propan_app) + + else: + schema_filepath = Path.cwd() / app + + schema = schema_filepath.read_text() - schema = get_schema_yaml(propan_app) serve_docs(schema, host, port) diff --git a/propan/cli/docs/gen.py b/propan/cli/docs/gen.py index 95db77fa..13010215 100644 --- a/propan/cli/docs/gen.py +++ b/propan/cli/docs/gen.py @@ -1,17 +1,21 @@ -from pathlib import Path -from typing import Dict +import json from io import StringIO +from pathlib import Path +from typing import Dict, cast import typer from propan.asyncapi import ( AsyncAPIChannel, + AsyncAPIComponents, AsyncAPIInfo, + AsyncAPIMessage, AsyncAPISchema, AsyncAPIServer, ) from propan.brokers._model import BrokerUsecase from propan.cli.app import PropanApp +from propan.types import AnyDict def generate_doc_file(app: PropanApp, filename: Path) -> None: @@ -23,42 +27,68 @@ def generate_doc_file(app: PropanApp, filename: Path) -> None: def get_schema_yaml(app: PropanApp) -> str: try: import yaml - except ImportError as e: + except ImportError as e: # pragma: no cover typer.echo( "To generate documentation, please install the dependencies\n" 'pip install "propan[doc]"' ) - raise typer.Exit() from e + raise typer.Exit(1) from e if app.broker is None: - typer.echo("Your PropanApp has no broker") - raise typer.Exit() - - schema = get_app_schema(app).dict( - by_alias=True, - exclude_none=True, - ) + raise typer.BadParameter("Your PropanApp has no broker") + schema = get_schema_json(app) io = StringIO(initial_value="", newline="\n") yaml.dump(schema, io, sort_keys=False) return io.getvalue() +def get_schema_json(app: PropanApp) -> AnyDict: + return cast( + AnyDict, + json.loads( + get_app_schema(app).json( + by_alias=True, + exclude_none=True, + ) + ), + ) + + def get_app_schema(app: PropanApp) -> AsyncAPISchema: if not isinstance(app.broker, BrokerUsecase): - typer.echo("Your PropanApp broker is invalid") - raise typer.Exit() + raise typer.BadParameter("Your PropanApp broker is invalid") servers = _get_broker_servers(app.broker) + messages: Dict[str, AsyncAPIMessage] = {} + payloads: Dict[str, AnyDict] = {} + channels = _get_broker_channels(app.broker) for ch in channels.values(): ch.servers = list(servers.keys()) + if ch.subscribe is not None: # pragma: no branch + m = ch.subscribe.message + m_title = m.title or "Message" + + p = m.payload + p_title = p.get("title", m_title) + payloads[p_title] = p + + m.payload = {"$ref": f"#/components/schemas/{p_title}"} + + messages[m_title] = m + ch.subscribe.message = {"$ref": f"#/components/messages/{m_title}"} # type: ignore + schema = AsyncAPISchema( info=_get_app_info(app), servers=servers, channels=channels, + components=AsyncAPIComponents( + messages=messages, + schemas=payloads, + ), ) return schema @@ -68,6 +98,8 @@ def _get_app_info(app: PropanApp) -> AsyncAPIInfo: title=app.title, version=app.version, description=app.description, + license=app.license, + contact=app.contact, ) @@ -81,6 +113,7 @@ def _get_broker_servers(broker: BrokerUsecase) -> Dict[str, AsyncAPIServer]: "dev": AsyncAPIServer( url=url, protocol=broker.protocol, + protocolVersion=broker.protocol_version, ) } diff --git a/propan/cli/startproject/utils.py b/propan/cli/startproject/utils.py index 7d41c4f4..60bcf2a3 100644 --- a/propan/cli/startproject/utils.py +++ b/propan/cli/startproject/utils.py @@ -1,13 +1,8 @@ from pathlib import Path -from typing import Union, cast -def touch_dir(dir: Union[Path, str]) -> Path: - if isinstance(dir, str) is True: - dir = Path(dir).resolve() - - dir = cast(Path, dir) - if dir.exists() is False: +def touch_dir(dir: Path) -> Path: + if not dir.exists(): # pragma: no branch dir.mkdir() return dir diff --git a/propan/cli/utils/imports.py b/propan/cli/utils/imports.py index 3724ab6b..e9b714c7 100644 --- a/propan/cli/utils/imports.py +++ b/propan/cli/utils/imports.py @@ -16,8 +16,9 @@ def try_import_propan(module: Path, app: str) -> PropanApp: except (ValueError, FileNotFoundError, AttributeError) as e: typer.echo(e, err=True) - typer.echo("Please, input module like [python_file:propan_app_name]", err=True) - raise typer.Exit() from e + raise typer.BadParameter( + "Please, input module like [python_file:propan_app_name]" + ) from e else: return propan_app diff --git a/propan/fastapi/kafka/router.pyi b/propan/fastapi/kafka/router.pyi index ca006ae1..626f1092 100644 --- a/propan/fastapi/kafka/router.pyi +++ b/propan/fastapi/kafka/router.pyi @@ -26,13 +26,7 @@ from propan.types import AnyCallable Partition = TypeVar("Partition") -<<<<<<< HEAD -class KafkaRouter(PropanRouter): - broker: KafkaBroker - -======= class KafkaRouter(PropanRouter[KafkaBroker]): ->>>>>>> 1acd1a468477ed27a085d3d1c6f38d967e64f1f9 def __init__( self, bootstrap_servers: Union[str, List[str]] = "localhost", diff --git a/propan/fastapi/nats/router.pyi b/propan/fastapi/nats/router.pyi index b09191e7..b52a5dca 100644 --- a/propan/fastapi/nats/router.pyi +++ b/propan/fastapi/nats/router.pyi @@ -32,13 +32,7 @@ from propan.fastapi.core.router import PropanRouter from propan.log import access_logger from propan.types import AnyCallable -<<<<<<< HEAD -class NatsRouter(PropanRouter): - broker: NatsBroker - -======= class NatsRouter(PropanRouter[NatsBroker]): ->>>>>>> 1acd1a468477ed27a085d3d1c6f38d967e64f1f9 def __init__( self, servers: Union[str, List[str]] = ["nats://localhost:4222"], # noqa: B006 diff --git a/propan/fastapi/rabbit/router.pyi b/propan/fastapi/rabbit/router.pyi index 98b42cb0..df667cc6 100644 --- a/propan/fastapi/rabbit/router.pyi +++ b/propan/fastapi/rabbit/router.pyi @@ -19,13 +19,7 @@ from propan.fastapi.core import PropanRouter from propan.log import access_logger from propan.types import AnyCallable -<<<<<<< HEAD -class RabbitRouter(PropanRouter): - broker: RabbitBroker - -======= class RabbitRouter(PropanRouter[RabbitBroker]): ->>>>>>> 1acd1a468477ed27a085d3d1c6f38d967e64f1f9 def __init__( self, host: str = "localhost", diff --git a/propan/fastapi/redis/router.pyi b/propan/fastapi/redis/router.pyi index 6042754c..835b27a7 100644 --- a/propan/fastapi/redis/router.pyi +++ b/propan/fastapi/redis/router.pyi @@ -16,13 +16,7 @@ from propan.fastapi.core.router import PropanRouter from propan.log import access_logger from propan.types import AnyCallable -<<<<<<< HEAD -class RedisRouter(PropanRouter): - broker: RedisBroker - -======= class RedisRouter(PropanRouter[RedisBroker]): ->>>>>>> 1acd1a468477ed27a085d3d1c6f38d967e64f1f9 def __init__( self, url: str = "redis://localhost:6379", diff --git a/propan/fastapi/sqs/router.pyi b/propan/fastapi/sqs/router.pyi index 673a54fc..a9d3e17a 100644 --- a/propan/fastapi/sqs/router.pyi +++ b/propan/fastapi/sqs/router.pyi @@ -17,13 +17,7 @@ from propan.fastapi.core.router import PropanRouter from propan.log import access_logger from propan.types import AnyCallable -<<<<<<< HEAD -class SQSRouter(PropanRouter): - broker: SQSBroker - -======= class SQSRouter(PropanRouter[SQSBroker]): ->>>>>>> 1acd1a468477ed27a085d3d1c6f38d967e64f1f9 def __init__( self, url: str = "http://localhost:9324/", diff --git a/propan/utils/functions.py b/propan/utils/functions.py index 9dc276cc..d3f63f86 100644 --- a/propan/utils/functions.py +++ b/propan/utils/functions.py @@ -23,13 +23,13 @@ async def wrapper(*args: P.args, **kwargs: P.kwargs) -> T: return wrapper -def get_function_arguments(func: Callable[P, T]) -> List[str]: +def get_function_positional_arguments(func: Callable[P, T]) -> List[str]: signature = inspect.signature(func) - arg_kinds = [ + arg_kinds = ( inspect.Parameter.POSITIONAL_ONLY, inspect.Parameter.POSITIONAL_OR_KEYWORD, - ] + ) return [ param.name for param in signature.parameters.values() if param.kind in arg_kinds diff --git a/pyproject.toml b/pyproject.toml index 8318c3bd..bfe4e4e5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -103,6 +103,7 @@ test = [ "pytest-asyncio>=0.21", "fastapi", + "python-dotenv", "asyncmock; python_version < '3.8'", ] diff --git a/tests/asyncapi/__init__.py b/tests/asyncapi/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/asyncapi/handler/__init__.py b/tests/asyncapi/handler/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/asyncapi/handler/test_base_arguments.py b/tests/asyncapi/handler/test_base_arguments.py new file mode 100644 index 00000000..fc31bef4 --- /dev/null +++ b/tests/asyncapi/handler/test_base_arguments.py @@ -0,0 +1,188 @@ +from fast_depends.construct import get_dependant +from pydantic import BaseModel + +from propan.brokers._model.schemas import BaseHandler + + +def test_base(): + def func(a: int): + ... + + handler = BaseHandler(func, get_dependant(path="", call=func)) + + message_title, result, response = handler.get_message_object() + + assert message_title == "FuncMessage" + + assert isinstance(result.pop("example"), int) + assert result == { + "title": "FuncPayload", + "type": "integer", + } + + assert response is None + + +def test_multi_args(): + def func(a: int, b: float): + ... + + handler = BaseHandler(func, get_dependant(path="", call=func)) + + message_title, result, response = handler.get_message_object() + + assert message_title == "FuncMessage" + + example = result.pop("example") + assert isinstance(example["a"], int) + assert isinstance(example["b"], float) + assert result == { + "properties": { + "a": {"title": "A", "type": "integer"}, + "b": {"title": "B", "type": "number"}, + }, + "required": ["a", "b"], + "title": "FuncPayload", + "type": "object", + } + + assert response is None + + +def test_pydantic_args(): + class Message(BaseModel): + a: int + b: float + + def func(a: Message): + ... + + handler = BaseHandler(func, get_dependant(path="", call=func)) + + message_title, result, response = handler.get_message_object() + + assert message_title == "FuncMessage" + + example = result.pop("example") + assert isinstance(example["a"], int) + assert isinstance(example["b"], float) + assert result == { + "properties": { + "a": {"title": "A", "type": "integer"}, + "b": {"title": "B", "type": "number"}, + }, + "required": ["a", "b"], + "title": "Message", + "type": "object", + } + + assert response is None + + +def test_pydantic_example(): + class Message(BaseModel): + a: int + + class Config: + schema_extra = {"example": {"a": 1}} + + def func(a: Message): + ... + + handler = BaseHandler(func, get_dependant(path="", call=func)) + + message_title, result, response = handler.get_message_object() + + assert message_title == "FuncMessage" + assert result == { + "example": {"a": 1}, + "properties": { + "a": {"title": "A", "type": "integer"}, + }, + "required": ["a"], + "title": "Message", + "type": "object", + } + + assert response is None + + +def test_response_base(): + def func() -> str: + ... + + handler = BaseHandler(func, get_dependant(path="", call=func)) + + message_title, result, response = handler.get_message_object() + + assert message_title == "FuncMessage" + assert result == { + "title": "FuncPayload", + "type": "null", + } + + for r in response.pop("examples"): + assert isinstance(r, str) + + assert response == {"title": "FuncReply", "type": "string"} + + +def test_pydantic_response(): + class Message(BaseModel): + a: int + + class Config: + schema_extra = {"example": {"a": 1}} + + def func() -> Message: + ... + + handler = BaseHandler(func, get_dependant(path="", call=func)) + + message_title, result, response = handler.get_message_object() + + assert message_title == "FuncMessage" + assert result == { + "title": "FuncPayload", + "type": "null", + } + + assert response == { + "examples": [{"a": 1}], + "properties": { + "a": {"title": "A", "type": "integer"}, + }, + "required": ["a"], + "title": "Message", + "type": "object", + } + + +def test_pydantic_gen_response_examples(): + class Message(BaseModel): + a: int + + def func() -> Message: + ... + + handler = BaseHandler(func, get_dependant(path="", call=func)) + + message_title, result, response = handler.get_message_object() + + assert message_title == "FuncMessage" + assert result == { + "title": "FuncPayload", + "type": "null", + } + + for r in response.pop("examples"): + assert isinstance(r["a"], int) + + assert response == { + "properties": { + "a": {"title": "A", "type": "integer"}, + }, + "required": ["a"], + "title": "Message", + "type": "object", + } diff --git a/tests/asyncapi/handler/test_dependencies_arguments.py b/tests/asyncapi/handler/test_dependencies_arguments.py new file mode 100644 index 00000000..de29362e --- /dev/null +++ b/tests/asyncapi/handler/test_dependencies_arguments.py @@ -0,0 +1,60 @@ +from fast_depends.construct import get_dependant + +from propan import Depends +from propan.brokers._model.schemas import BaseHandler + + +def test_base(): + def dep(a: int): + ... + + def func(a=Depends(dep)): + ... + + handler = BaseHandler(func, get_dependant(path="", call=func)) + + message_title, result, response = handler.get_message_object() + + assert message_title == "FuncMessage" + + assert isinstance(result.pop("example"), int) + assert result == { + "title": "FuncPayload", + "type": "integer", + } + + assert response is None + + +def test_multi_args(): + def dep2(c: int): + ... + + def dep(a: int, _=Depends(dep2)): + ... + + def func(b: float, _=Depends(dep)): + ... + + handler = BaseHandler(func, get_dependant(path="", call=func)) + + message_title, result, response = handler.get_message_object() + + assert message_title == "FuncMessage" + + example = result.pop("example") + assert isinstance(example["a"], int) + assert isinstance(example["c"], int) + assert isinstance(example["b"], float) + assert result == { + "properties": { + "a": {"title": "A", "type": "integer"}, + "b": {"title": "B", "type": "number"}, + "c": {"title": "C", "type": "integer"}, + }, + "required": ["b", "a", "c"], + "title": "FuncPayload", + "type": "object", + } + + assert response is None diff --git a/tests/asyncapi/kafka/__init__.py b/tests/asyncapi/kafka/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/asyncapi/kafka/test_handler.py b/tests/asyncapi/kafka/test_handler.py new file mode 100644 index 00000000..2980759f --- /dev/null +++ b/tests/asyncapi/kafka/test_handler.py @@ -0,0 +1,56 @@ +from propan import KafkaBroker, PropanApp +from propan.cli.docs.gen import get_schema_json + + +def test_base_handler(): + broker = KafkaBroker() + + @broker.handle("test") + async def handler(a: int): + ... + + schema = get_schema_json(PropanApp(broker)) + assert schema["channels"] == { + "Handler": { + "bindings": {"kafka": {"bindingVersion": "0.4.0", "topic": ["test"]}}, + "servers": ["dev"], + "subscribe": {"message": {"$ref": "#/components/messages/HandlerMessage"}}, + } + } + + +def test_group_handler(): + broker = KafkaBroker() + + @broker.handle("test", group_id="workers") + async def handler(a: int) -> str: + ... + + schema = get_schema_json(PropanApp(broker)) + + assert isinstance( + schema["channels"]["Handler"]["subscribe"]["bindings"]["kafka"]["replyTo"].pop( + "examples" + )[0], + str, + ) + + assert schema["channels"] == { + "Handler": { + "bindings": {"kafka": {"bindingVersion": "0.4.0", "topic": ["test"]}}, + "servers": ["dev"], + "subscribe": { + "bindings": { + "kafka": { + "bindingVersion": "0.4.0", + "groupId": {"enum": ["workers"], "type": "string"}, + "replyTo": { + "title": "HandlerReply", + "type": "string", + }, + } + }, + "message": {"$ref": "#/components/messages/HandlerMessage"}, + }, + } + } diff --git a/tests/asyncapi/kafka/test_server.py b/tests/asyncapi/kafka/test_server.py new file mode 100644 index 00000000..9b90285c --- /dev/null +++ b/tests/asyncapi/kafka/test_server.py @@ -0,0 +1,28 @@ +from propan import KafkaBroker, PropanApp +from propan.cli.docs.gen import get_schema_json + + +def test_server_info(): + schema = get_schema_json(PropanApp(KafkaBroker())) + assert schema["servers"]["dev"] == { + "protocol": "kafka", + "url": "localhost", + "protocolVersion": "auto", + } + + +def test_server_custom_info(): + schema = get_schema_json( + PropanApp( + KafkaBroker( + "kafka:9092", + protocol="kafka-secury", + api_version="1.0.0", + ) + ) + ) + assert schema["servers"]["dev"] == { + "protocol": "kafka-secury", + "url": "kafka:9092", + "protocolVersion": "1.0.0", + } diff --git a/tests/asyncapi/nats/__init__.py b/tests/asyncapi/nats/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/asyncapi/nats/test_handler.py b/tests/asyncapi/nats/test_handler.py new file mode 100644 index 00000000..1824f6a8 --- /dev/null +++ b/tests/asyncapi/nats/test_handler.py @@ -0,0 +1,61 @@ +from propan import NatsBroker, PropanApp +from propan.cli.docs.gen import get_schema_json + + +def test_base_handler(): + broker = NatsBroker() + + @broker.handle("test") + async def handler(a: int): + ... + + schema = get_schema_json(PropanApp(broker)) + assert schema["channels"] == { + "Handler": { + "bindings": {"nats": {"bindingVersion": "custom", "subject": "test"}}, + "servers": ["dev"], + "subscribe": { + "bindings": {"nats": {"bindingVersion": "custom"}}, + "message": {"$ref": "#/components/messages/HandlerMessage"}, + }, + } + } + + +def test_group_handler(): + broker = NatsBroker() + + @broker.handle("*test", queue="workers") + async def handler(a: int) -> str: + ... + + schema = get_schema_json(PropanApp(broker)) + + assert isinstance( + schema["channels"]["Handler"]["subscribe"]["bindings"]["nats"]["replyTo"].pop( + "examples" + )[0], + str, + ) + + assert schema["channels"] == { + "Handler": { + "bindings": { + "nats": { + "bindingVersion": "custom", + "queue": "workers", + "subject": "*test", + } + }, + "servers": ["dev"], + "subscribe": { + "bindings": { + "nats": { + "bindingVersion": "custom", + "replyTo": {"title": "HandlerReply", "type": "string"}, + } + }, + "message": {"$ref": "#/components/messages/HandlerMessage"}, + }, + } + } diff --git a/tests/asyncapi/nats/test_server.py b/tests/asyncapi/nats/test_server.py new file mode 100644 index 00000000..8e4a4978 --- /dev/null +++ b/tests/asyncapi/nats/test_server.py @@ -0,0 +1,10 @@ +from propan import NatsBroker, PropanApp +from propan.cli.docs.gen import get_schema_json + + +def test_server_info(): + schema = get_schema_json(PropanApp(NatsBroker())) + assert schema["servers"]["dev"] == { + "protocol": "nats", + "url": "nats://localhost:4222", + } diff --git a/tests/asyncapi/rabbit/__init__.py b/tests/asyncapi/rabbit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/asyncapi/rabbit/test_handler.py b/tests/asyncapi/rabbit/test_handler.py new file mode 100644 index 00000000..933e0491 --- /dev/null +++ b/tests/asyncapi/rabbit/test_handler.py @@ -0,0 +1,115 @@ +from propan import PropanApp, RabbitBroker +from propan.brokers.rabbit import ExchangeType, RabbitExchange +from propan.cli.docs.gen import get_schema_json + + +def test_base_handler(): + broker = RabbitBroker() + + @broker.handle("test") + async def handler(a: int): + ... + + schema = get_schema_json(PropanApp(broker)) + + assert schema["channels"] == { + "Handler": { + "bindings": { + "amqp": { + "bindingVersion": "0.2.0", + "exchange": {"type": "default", "vhost": "/"}, + "is": "routingKey", + "queue": { + "autoDelete": False, + "durable": False, + "exclusive": False, + "name": "test", + "vhost": "/", + }, + } + }, + "servers": ["dev"], + "subscribe": { + "bindings": { + "amqp": {"ack": True, "bindingVersion": "0.2.0", "cc": "test"} + }, + "message": {"$ref": "#/components/messages/HandlerMessage"}, + }, + } + } + + +def test_fanout_exchange_handler(): + broker = RabbitBroker() + + @broker.handle("test", RabbitExchange("test", type=ExchangeType.FANOUT)) + async def handler(a: int): + """Test description""" + ... + + schema = get_schema_json(PropanApp(broker)) + assert schema["channels"] == { + "Handler": { + "bindings": { + "amqp": { + "bindingVersion": "0.2.0", + "exchange": { + "autoDelete": False, + "durable": False, + "name": "test", + "type": "fanout", + "vhost": "/", + }, + "is": "routingKey", + } + }, + "servers": ["dev"], + "subscribe": { + "bindings": {"amqp": {"ack": True, "bindingVersion": "0.2.0"}}, + "description": "Test description", + "message": {"$ref": "#/components/messages/HandlerMessage"}, + }, + } + } + + +def test_direct_exchange_handler(): + broker = RabbitBroker() + + @broker.handle("test", RabbitExchange("test"), description="Test description") + async def handler(a: int): + ... + + schema = get_schema_json(PropanApp(broker)) + assert schema["channels"] == { + "Handler": { + "bindings": { + "amqp": { + "bindingVersion": "0.2.0", + "exchange": { + "autoDelete": False, + "durable": False, + "name": "test", + "type": "direct", + "vhost": "/", + }, + "is": "routingKey", + "queue": { + "autoDelete": False, + "durable": False, + "exclusive": False, + "name": "test", + "vhost": "/", + }, + } + }, + "servers": ["dev"], + "subscribe": { + "bindings": { + "amqp": {"ack": True, "bindingVersion": "0.2.0", "cc": "test"} + }, + "description": "Test description", + "message": {"$ref": "#/components/messages/HandlerMessage"}, + }, + } + } diff --git a/tests/asyncapi/rabbit/test_server.py b/tests/asyncapi/rabbit/test_server.py new file mode 100644 index 00000000..1d402b8e --- /dev/null +++ b/tests/asyncapi/rabbit/test_server.py @@ -0,0 +1,26 @@ +from propan import PropanApp, RabbitBroker +from propan.cli.docs.gen import get_schema_json + + +def test_server_info(): + schema = get_schema_json(PropanApp(RabbitBroker())) + assert schema["servers"]["dev"] == { + "protocol": "amqp", + "url": "amqp://guest:guest@localhost:5672/", + "protocolVersion": "0.9.1", + } + + +def test_server_custom_info(): + schema = get_schema_json( + PropanApp( + RabbitBroker( + "amqps://rabbithost.com", protocol="amqps", protocol_version="0.8.0" + ) + ) + ) + assert schema["servers"]["dev"] == { + "protocol": "amqps", + "url": "amqps://rabbithost.com", + "protocolVersion": "0.8.0", + } diff --git a/tests/asyncapi/redis/__init__.py b/tests/asyncapi/redis/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/asyncapi/redis/test_handler.py b/tests/asyncapi/redis/test_handler.py new file mode 100644 index 00000000..2bfe997b --- /dev/null +++ b/tests/asyncapi/redis/test_handler.py @@ -0,0 +1,68 @@ +from propan import PropanApp, RedisBroker +from propan.cli.docs.gen import get_schema_json + + +def test_base_handler(): + broker = RedisBroker() + + @broker.handle("test") + async def handler(a: int): + ... + + schema = get_schema_json(PropanApp(broker)) + + assert schema["channels"] == { + "Handler": { + "bindings": { + "redis": { + "bindingVersion": "custom", + "channel": "test", + "method": "subscribe", + } + }, + "servers": ["dev"], + "subscribe": { + "bindings": {"redis": {"bindingVersion": "custom"}}, + "message": {"$ref": "#/components/messages/HandlerMessage"}, + }, + } + } + + +def test_group_handler(): + broker = RedisBroker() + + @broker.handle("*test", pattern=True) + async def handler(a: int) -> str: + ... + + schema = get_schema_json(PropanApp(broker)) + + assert isinstance( + schema["channels"]["Handler"]["subscribe"]["bindings"]["redis"]["replyTo"].pop( + "examples" + )[0], + str, + ) + + assert schema["channels"] == { + "Handler": { + "bindings": { + "redis": { + "bindingVersion": "custom", + "channel": "*test", + "method": "psubscribe", + } + }, + "servers": ["dev"], + "subscribe": { + "bindings": { + "redis": { + "bindingVersion": "custom", + "replyTo": {"title": "HandlerReply", "type": "string"}, + } + }, + "message": {"$ref": "#/components/messages/HandlerMessage"}, + }, + } + } diff --git a/tests/asyncapi/redis/test_server.py b/tests/asyncapi/redis/test_server.py new file mode 100644 index 00000000..ed4747e1 --- /dev/null +++ b/tests/asyncapi/redis/test_server.py @@ -0,0 +1,10 @@ +from propan import PropanApp, RedisBroker +from propan.cli.docs.gen import get_schema_json + + +def test_server_info(): + schema = get_schema_json(PropanApp(RedisBroker())) + assert schema["servers"]["dev"] == { + "protocol": "redis", + "url": "redis://localhost:6379", + } diff --git a/tests/asyncapi/sqs/__init__.py b/tests/asyncapi/sqs/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/asyncapi/sqs/test_handler.py b/tests/asyncapi/sqs/test_handler.py new file mode 100644 index 00000000..2ff3676f --- /dev/null +++ b/tests/asyncapi/sqs/test_handler.py @@ -0,0 +1,66 @@ +from propan import PropanApp, SQSBroker +from propan.cli.docs.gen import get_schema_json + + +def test_base_handler(): + broker = SQSBroker() + + @broker.handle("test") + async def handler(a: int): + ... + + schema = get_schema_json(PropanApp(broker)) + + assert schema["channels"] == { + "Handler": { + "bindings": { + "sqs": { + "bindingVersion": "custom", + "queue": {"fifo": False, "name": "test"}, + } + }, + "servers": ["dev"], + "subscribe": { + "bindings": {"sqs": {"bindingVersion": "custom"}}, + "message": {"$ref": "#/components/messages/HandlerMessage"}, + }, + } + } + + +def test_group_handler(): + broker = SQSBroker() + + @broker.handle("test") + async def handler(a: int) -> str: + ... + + schema = get_schema_json(PropanApp(broker)) + + assert isinstance( + schema["channels"]["Handler"]["subscribe"]["bindings"]["sqs"]["replyTo"].pop( + "examples" + )[0], + str, + ) + + assert schema["channels"] == { + "Handler": { + "bindings": { + "sqs": { + "bindingVersion": "custom", + "queue": {"fifo": False, "name": "test"}, + } + }, + "servers": ["dev"], + "subscribe": { + "bindings": { + "sqs": { + "bindingVersion": "custom", + "replyTo": {"title": "HandlerReply", "type": "string"}, + } + }, + "message": {"$ref": "#/components/messages/HandlerMessage"}, + }, + } + } diff --git a/tests/asyncapi/sqs/test_server.py b/tests/asyncapi/sqs/test_server.py new file mode 100644 index 00000000..bd96581d --- /dev/null +++ b/tests/asyncapi/sqs/test_server.py @@ -0,0 +1,10 @@ +from propan import PropanApp, SQSBroker +from propan.cli.docs.gen import get_schema_json + + +def test_server_info(): + schema = get_schema_json(PropanApp(SQSBroker())) + assert schema["servers"]["dev"] == { + "protocol": "sqs", + "url": "http://localhost:9324/", + } diff --git a/tests/asyncapi/test_app_info.py b/tests/asyncapi/test_app_info.py new file mode 100644 index 00000000..6899ad25 --- /dev/null +++ b/tests/asyncapi/test_app_info.py @@ -0,0 +1,59 @@ +from propan import PropanApp, RabbitBroker +from propan.asyncapi import AsyncAPIContact, AsyncAPILicense +from propan.cli.docs.gen import get_schema_json + + +def test_app_default_info(): + schema = get_schema_json(PropanApp(RabbitBroker())) + assert schema["info"] == { + "description": "", + "title": "Propan", + "version": "0.1.0", + } + + +def test_app_base_info(): + schema = get_schema_json( + PropanApp( + RabbitBroker(), + title="My App", + description="description", + version="1.0.0", + ) + ) + assert schema["info"] == { + "description": "description", + "title": "My App", + "version": "1.0.0", + } + + +def test_app_detail_info(): + schema = get_schema_json( + PropanApp( + RabbitBroker(), + title="My App", + description="description", + version="1.0.0", + license=AsyncAPILicense(name="MIT", url="http://mit.com"), + contact=AsyncAPIContact( + name="Developer", + url="http://my-domain.com", + email="my-domain@gmail.com", + ), + ) + ) + assert schema["info"] == { + "contact": { + "email": "my-domain@gmail.com", + "name": "Developer", + "url": "http://my-domain.com", + }, + "description": "description", + "license": { + "name": "MIT", + "url": "http://mit.com", + }, + "title": "My App", + "version": "1.0.0", + } diff --git a/tests/brokers/base/rpc.py b/tests/brokers/base/rpc.py index a1d606c4..6ca9558c 100644 --- a/tests/brokers/base/rpc.py +++ b/tests/brokers/base/rpc.py @@ -80,3 +80,25 @@ async def m(): # pragma: no cover await asyncio.wait_for(consume.wait(), 3) mock.assert_called_with("1") + + @pytest.mark.asyncio + async def test_unwrap(self, queue: str, full_broker: BrokerUsecase): + @full_broker.handle(queue) + async def m(a: int, b: int): # pragma: no cover + assert a == 1 + assert b == 1 + return "1" + + async with full_broker: + await full_broker.start() + + r = await full_broker.publish( + { + "a": 1, + "b": 1, + }, + queue, + callback_timeout=3, + callback=True, + ) + assert r == "1" diff --git a/tests/brokers/kafka/test_connect.py b/tests/brokers/kafka/test_connect.py index 480d9f8a..22b8e56d 100644 --- a/tests/brokers/kafka/test_connect.py +++ b/tests/brokers/kafka/test_connect.py @@ -9,7 +9,7 @@ class TestKafkaConnect(BrokerConnectionTestcase): broker = KafkaBroker @pytest.mark.asyncio - async def test_connect_merge_args_and_kwargs(self, settings): + async def test_connect_merge_args_and_kwargs_native(self, settings): broker = self.broker("fake-url") # will be ignored assert await broker.connect(bootstrap_servers=settings.url) await broker.close() diff --git a/tests/brokers/nats/test_connect.py b/tests/brokers/nats/test_connect.py index 1cfa4ab0..02874474 100644 --- a/tests/brokers/nats/test_connect.py +++ b/tests/brokers/nats/test_connect.py @@ -9,7 +9,7 @@ class TestNatsConnect(BrokerConnectionTestcase): broker = NatsBroker @pytest.mark.asyncio - async def test_connect_merge_args_and_kwargs(self, settings): + async def test_connect_merge_args_and_kwargs_native(self, settings): broker = self.broker("fake-url") # will be ignored assert await broker.connect(servers=settings.url) await broker.close() diff --git a/tests/brokers/rabbit/test_connect.py b/tests/brokers/rabbit/test_connect.py index 0613bd53..adb4d743 100644 --- a/tests/brokers/rabbit/test_connect.py +++ b/tests/brokers/rabbit/test_connect.py @@ -42,7 +42,7 @@ async def test_connect_merge_kwargs_with_priority(self, settings): await broker.close() @pytest.mark.asyncio - async def test_connect_merge_args_and_kwargs(self, settings): + async def test_connect_merge_args_and_kwargs_native(self, settings): broker = self.broker("fake-url") # will be ignored assert await broker.connect(url=settings.url) await broker.close() diff --git a/tests/brokers/redis/test_connect.py b/tests/brokers/redis/test_connect.py index bb1fbc09..edc1899b 100644 --- a/tests/brokers/redis/test_connect.py +++ b/tests/brokers/redis/test_connect.py @@ -31,7 +31,7 @@ async def test_connect_merge_kwargs_with_priority(self, settings): await broker.close() @pytest.mark.asyncio - async def test_connect_merge_args_and_kwargs(self, settings): + async def test_connect_merge_args_and_kwargs_native(self, settings): broker = self.broker("fake-url") # will be ignored assert await broker.connect(url=settings.url) await broker.close() diff --git a/tests/brokers/sqs/test_connect.py b/tests/brokers/sqs/test_connect.py index f8cf02eb..10658d38 100644 --- a/tests/brokers/sqs/test_connect.py +++ b/tests/brokers/sqs/test_connect.py @@ -17,7 +17,7 @@ def get_broker_args(self, settings): } @pytest.mark.asyncio - async def test_connect_merge_args_and_kwargs(self, settings): + async def test_connect_merge_args_and_kwargs_native(self, settings): args, kwargs = self.get_broker_args(settings) broker = self.broker("fake-url") # will be ignored assert await broker.connect(url=settings.url, **kwargs) diff --git a/tests/cli/conftest.py b/tests/cli/conftest.py index d0de9468..5b08c368 100644 --- a/tests/cli/conftest.py +++ b/tests/cli/conftest.py @@ -1,67 +1,70 @@ -from tempfile import TemporaryDirectory +from pathlib import Path import pytest from typer.testing import CliRunner from propan import PropanApp from propan.brokers.rabbit import RabbitBroker -from propan.cli.startproject.async_app.kafka import create_kafka -from propan.cli.startproject.async_app.nats import create_nats -from propan.cli.startproject.async_app.rabbit import create_rabbit -from propan.cli.startproject.async_app.redis import create_redis -from propan.cli.startproject.async_app.sqs import create_sqs +from propan.cli import cli -@pytest.fixture +@pytest.fixture() def broker(): yield RabbitBroker() -@pytest.fixture +@pytest.fixture() def app_without_logger(broker): return PropanApp(broker, None) -@pytest.fixture +@pytest.fixture() def app_without_broker(): return PropanApp() -@pytest.fixture +@pytest.fixture() def app(broker): return PropanApp(broker) -@pytest.fixture -def runner(): - return CliRunner() +@pytest.fixture(scope="session") +def runner() -> CliRunner: + runner = CliRunner() + with runner.isolated_filesystem(): + yield runner -@pytest.fixture(scope="module") -def rabbit_async_project(): - with TemporaryDirectory() as dir: - yield create_rabbit(dir) +@pytest.fixture(scope="session") +def rabbit_async_project(runner: CliRunner) -> Path: + project_name = "rabbit" + runner.invoke(cli, ["create", "async", "rabbit", project_name]) + yield Path.cwd() / Path(project_name) -@pytest.fixture(scope="module") -def redis_async_project(): - with TemporaryDirectory() as dir: - yield create_redis(dir) +@pytest.fixture(scope="session") +def redis_async_project(runner: CliRunner) -> Path: + project_name = "redis" + runner.invoke(cli, ["create", "async", "redis", project_name]) + yield Path.cwd() / Path(project_name) -@pytest.fixture(scope="module") -def nats_async_project(): - with TemporaryDirectory() as dir: - yield create_nats(dir) +@pytest.fixture(scope="session") +def nats_async_project(runner: CliRunner) -> Path: + project_name = "nats" + runner.invoke(cli, ["create", "async", "nats", project_name]) + yield Path.cwd() / Path(project_name) -@pytest.fixture(scope="module") -def kafka_async_project(): - with TemporaryDirectory() as dir: - yield create_kafka(dir) +@pytest.fixture(scope="session") +def kafka_async_project(runner: CliRunner) -> Path: + project_name = "kafka" + runner.invoke(cli, ["create", "async", "kafka", project_name]) + yield Path.cwd() / Path(project_name) -@pytest.fixture(scope="module") -def sqs_async_project(): - with TemporaryDirectory() as dir: - yield create_sqs(dir) +@pytest.fixture(scope="session") +def sqs_async_project(runner: CliRunner) -> Path: + project_name = "sqs" + runner.invoke(cli, ["create", "async", "sqs", project_name]) + yield Path.cwd() / Path(project_name) diff --git a/tests/cli/test_doc.py b/tests/cli/test_doc.py new file mode 100644 index 00000000..c8949b05 --- /dev/null +++ b/tests/cli/test_doc.py @@ -0,0 +1,59 @@ +from pathlib import Path +from unittest.mock import Mock + +import uvicorn +import yaml +from typer.testing import CliRunner + +from propan.cli.main import cli + + +def test_gen_rabbit_docs(runner: CliRunner, rabbit_async_project: Path): + app_path = f'{rabbit_async_project / "app" / "serve"}:app' + r = runner.invoke(cli, ["docs", "gen", app_path]) + assert r.exit_code == 0 + + schema_path = rabbit_async_project.parent / "asyncapi.yaml" + assert schema_path.exists() + + with schema_path.open("r") as f: + schema = yaml.load(f, Loader=yaml.BaseLoader) + + assert schema + + +def test_gen_wrong_path(runner: CliRunner, rabbit_async_project: Path): + app_path = f'{rabbit_async_project / "app" / "serve"}:app1' + r = runner.invoke(cli, ["docs", "gen", app_path]) + assert r.exit_code == 2 + assert "Please, input module like [python_file:propan_app_name]" in r.stdout + + +def test_serve_rabbit_docs( + runner: CliRunner, + rabbit_async_project: Path, + monkeypatch, + mock: Mock, +): + app_path = f'{rabbit_async_project / "app" / "serve"}:app' + + with monkeypatch.context() as m: + m.setattr(uvicorn, "run", mock) + r = runner.invoke(cli, ["docs", "serve", app_path]) + + assert r.exit_code == 0 + mock.assert_called_once() + + +def test_serve_rabbit_schema( + runner: CliRunner, + rabbit_async_project: Path, + monkeypatch, + mock: Mock, +): + with monkeypatch.context() as m: + m.setattr(uvicorn, "run", mock) + r = runner.invoke(cli, ["docs", "serve", "asyncapi.yaml"]) + + assert r.exit_code == 0 + mock.assert_called_once() diff --git a/tests/cli/test_run.py b/tests/cli/test_run.py index a33aee42..343b3faf 100644 --- a/tests/cli/test_run.py +++ b/tests/cli/test_run.py @@ -1,68 +1,119 @@ -import sys -import time -from multiprocessing import Process +from pathlib import Path +from unittest.mock import Mock import pytest +from typer.testing import CliRunner -from propan.cli.main import _run -from propan.cli.utils.imports import get_app_path +from propan import PropanApp +from propan.cli import cli @pytest.mark.rabbit -@pytest.mark.slow -def test_run_rabbit_correct(rabbit_async_project): - module, app = get_app_path(f'{rabbit_async_project / "app" / "serve"}:app') - sys.path.insert(0, str(module.parent)) - p = Process(target=_run, args=(module, app, {})) - p.start() - time.sleep(0.1) - p.terminate() - p.join() +def test_run_rabbit_correct( + runner: CliRunner, + rabbit_async_project: Path, + monkeypatch, + mock: Mock, +): + app_path = f"{rabbit_async_project.name}.app.serve:app" + + async def patched_run(self: PropanApp, *args, **kwargs): + await self._startup() + await self._shutdown() + mock() + + with monkeypatch.context() as m: + m.setattr(PropanApp, "run", patched_run) + r = runner.invoke(cli, ["run", app_path]) + + assert r.exit_code == 0 + mock.assert_called_once() @pytest.mark.redis -@pytest.mark.slow -def test_run_redis_correct(redis_async_project): - module, app = get_app_path(f'{redis_async_project / "app" / "serve"}:app') - sys.path.insert(0, str(module.parent)) - p = Process(target=_run, args=(module, app, {})) - p.start() - time.sleep(0.1) - p.terminate() - p.join() +def test_run_redis_correct( + runner: CliRunner, + redis_async_project: Path, + monkeypatch, + mock: Mock, +): + app_path = f"{redis_async_project.name}.app.serve:app" + + async def patched_run(self: PropanApp, *args, **kwargs): + await self._startup() + await self._shutdown() + mock() + + with monkeypatch.context() as m: + m.setattr(PropanApp, "run", patched_run) + r = runner.invoke(cli, ["run", app_path]) + + assert r.exit_code == 0 + mock.assert_called_once() @pytest.mark.nats -@pytest.mark.slow -def test_run_nats_correct(nats_async_project): - module, app = get_app_path(f'{nats_async_project / "app" / "serve"}:app') - sys.path.insert(0, str(module.parent)) - p = Process(target=_run, args=(module, app, {})) - p.start() - time.sleep(0.1) - p.terminate() - p.join() +def test_run_nats_correct( + runner: CliRunner, + nats_async_project: Path, + monkeypatch, + mock: Mock, +): + app_path = f"{nats_async_project.name}.app.serve:app" + + async def patched_run(self: PropanApp, *args, **kwargs): + await self._startup() + await self._shutdown() + mock() + + with monkeypatch.context() as m: + m.setattr(PropanApp, "run", patched_run) + r = runner.invoke(cli, ["run", app_path]) + + assert r.exit_code == 0 + mock.assert_called_once() @pytest.mark.kafka -@pytest.mark.slow -def test_run_kafka_correct(kafka_async_project): - module, app = get_app_path(f'{kafka_async_project / "app" / "serve"}:app') - sys.path.insert(0, str(module.parent)) - p = Process(target=_run, args=(module, app, {})) - p.start() - time.sleep(0.1) - p.terminate() - p.join() +def test_run_kafka_correct( + runner: CliRunner, + kafka_async_project: Path, + monkeypatch, + mock: Mock, +): + app_path = f"{kafka_async_project.name}.app.serve:app" + + async def patched_run(self: PropanApp, *args, **kwargs): + await self._startup() + await self._shutdown() + mock() + + with monkeypatch.context() as m: + m.setattr(PropanApp, "run", patched_run) + r = runner.invoke(cli, ["run", app_path]) + + assert r.exit_code == 0 + mock.assert_called_once() @pytest.mark.sqs -@pytest.mark.slow -def test_run_sqs_correct(sqs_async_project): - module, app = get_app_path(f'{sqs_async_project / "app" / "serve"}:app') - sys.path.insert(0, str(module.parent)) - p = Process(target=_run, args=(module, app, {})) - p.start() - time.sleep(0.1) - p.terminate() - p.join() +@pytest.mark.xfail # TODO: fix it +def test_run_sqs_correct( + runner: CliRunner, + sqs_async_project: Path, + monkeypatch, + mock: Mock, +): + app_path = f"{sqs_async_project.name}.app.serve:app" + + async def patched_run(self: PropanApp, *args, **kwargs): + await self._startup() + await self._shutdown() + mock() + + with monkeypatch.context() as m: + m.setattr(PropanApp, "run", patched_run) + r = runner.invoke(cli, ["run", app_path]) + + assert r.exit_code == 0 + mock.assert_called_once() diff --git a/tests/cli/utils/test_imports.py b/tests/cli/utils/test_imports.py index 47e5d53d..4bcfb314 100644 --- a/tests/cli/utils/test_imports.py +++ b/tests/cli/utils/test_imports.py @@ -4,14 +4,6 @@ from propan.cli.utils.imports import get_app_path, import_object -test_object = Path(__file__) - - -def test_import(): - dir, app = get_app_path("tests.cli.utils.test_imports:test_object") - obj = import_object(dir, app) - assert obj == test_object - def test_import_wrong(): dir, app = get_app_path("tests:test_object") diff --git a/tests/tools/__init__.py b/tests/tools/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/tools/marks.py b/tests/tools/marks.py new file mode 100644 index 00000000..600626c6 --- /dev/null +++ b/tests/tools/marks.py @@ -0,0 +1,13 @@ +import sys + +import pytest + +needs_py310 = pytest.mark.skipif( + sys.version_info < (3, 10), reason="requires python3.10+" +) + +needs_py38 = pytest.mark.skipif(sys.version_info < (3, 8), reason="requires python3.8+") + +needs_ex_py37 = pytest.mark.skipif( + sys.version_info == (3, 8), reason="requires python3.7" +) From bc6bc7022c5bcc6dba5e999f341445fa96b7b39c Mon Sep 17 00:00:00 2001 From: Lancetnik Date: Wed, 7 Jun 2023 21:24:22 +0300 Subject: [PATCH 12/18] add AsyncAPI page serving --- propan/cli/docs/serve.py | 100 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 propan/cli/docs/serve.py diff --git a/propan/cli/docs/serve.py b/propan/cli/docs/serve.py new file mode 100644 index 00000000..61ebcc8d --- /dev/null +++ b/propan/cli/docs/serve.py @@ -0,0 +1,100 @@ +import json +from typing import Any, Dict, NoReturn, Union + + +def serve_docs( + schema: str, + host: str = "0.0.0.0", + port: int = 8000, +) -> None: + import uvicorn + from fastapi import FastAPI + from fastapi.responses import HTMLResponse + + app = FastAPI() + + @app.get("/", response_class=HTMLResponse) + async def read_items( + sidebar: bool = True, + info: bool = True, + servers: bool = True, + operations: bool = True, + messages: bool = True, + schemas: bool = True, + errors: bool = True, + expandMessageExamples: bool = True, + ) -> str: + return get_asyncapi_html( + schema, + sidebar=sidebar, + info=info, + servers=servers, + operations=operations, + messages=messages, + schemas=schemas, + errors=errors, + expand_message_examples=expandMessageExamples, + ) + + uvicorn.run(app, host=host, port=port) + + +def get_asyncapi_html( + schema: Union[str, Dict[str, Any]], + sidebar: bool = True, + info: bool = True, + servers: bool = True, + operations: bool = True, + messages: bool = True, + schemas: bool = True, + errors: bool = True, + expand_message_examples: bool = True, +) -> str: + config = { + "schema": schema, + "config": { + "show": { + "sidebar": sidebar, + "info": info, + "servers": servers, + "operations": operations, + "messages": messages, + "schemas": schemas, + "errors": errors, + }, + "expand": { + "messageExamples": expand_message_examples, + }, + "sidebar": { + "showServers": "byDefault", + "showOperations": "byDefault", + }, + }, + } + + return """ + + + + Propan AsyncAPI + + + + + + +
+ + + """ + f""" + + + + """ From 345b9228d6eb24a9481a18c18332be21d1989893 Mon Sep 17 00:00:00 2001 From: Lancetnik Date: Sat, 10 Jun 2023 17:10:06 +0300 Subject: [PATCH 13/18] serve fastapi docs too --- asyncapi_docs/kafka_full.yaml | 149 ------------------ asyncapi_docs/rpc_client.yaml | 69 -------- asyncapi_docs/rpc_server.yaml | 66 -------- asyncapi_docs/title_min.yaml | 24 --- docs/docs/assets/img/docs-html-short.png | Bin 0 -> 249445 bytes docs/docs/assets/img/docs-html.png | Bin 0 -> 382283 bytes .../en/getting_started/9_documentation.md | 0 .../ru/getting_started/9_documentation.md | 86 ++++++++++ docs/docs/ru/index.md | 1 + .../quickstart/documentation/custom_schema.py | 12 ++ .../quickstart/documentation/example.py | 23 +++ .../quickstart/documentation/example.yaml | 67 ++++++++ .../quickstart/documentation/fastapi.py | 6 + docs/mkdocs.yml | 2 + .../native_fastapi.py | 4 +- propan/brokers/_model/broker_usecase.py | 19 ++- propan/brokers/_model/schemas.py | 2 +- propan/cli/docs/app.py | 2 +- propan/cli/docs/gen.py | 6 +- propan/cli/docs/serve.py | 97 +++++++----- propan/cli/main.py | 2 +- propan/fastapi/core/route.py | 10 +- propan/fastapi/core/router.py | 72 ++++++++- propan/fastapi/kafka/router.pyi | 14 ++ propan/fastapi/nats/router.pyi | 12 ++ propan/fastapi/rabbit/router.pyi | 13 ++ propan/fastapi/redis/router.pyi | 13 +- propan/fastapi/sqs/router.pyi | 13 +- tests/brokers/base/test_pushback.py | 8 +- tests/fastapi/case.py | 2 +- 30 files changed, 427 insertions(+), 367 deletions(-) delete mode 100644 asyncapi_docs/kafka_full.yaml delete mode 100644 asyncapi_docs/rpc_client.yaml delete mode 100644 asyncapi_docs/rpc_server.yaml delete mode 100644 asyncapi_docs/title_min.yaml create mode 100644 docs/docs/assets/img/docs-html-short.png create mode 100644 docs/docs/assets/img/docs-html.png create mode 100644 docs/docs/en/getting_started/9_documentation.md create mode 100644 docs/docs/ru/getting_started/9_documentation.md create mode 100644 docs/docs_src/quickstart/documentation/custom_schema.py create mode 100644 docs/docs_src/quickstart/documentation/example.py create mode 100644 docs/docs_src/quickstart/documentation/example.yaml create mode 100644 docs/docs_src/quickstart/documentation/fastapi.py diff --git a/asyncapi_docs/kafka_full.yaml b/asyncapi_docs/kafka_full.yaml deleted file mode 100644 index 2755c451..00000000 --- a/asyncapi_docs/kafka_full.yaml +++ /dev/null @@ -1,149 +0,0 @@ -asyncapi: '2.6.0' -info: - title: Streetlights Kafka API - version: '1.0.0' - description: | - The Smartylighting Streetlights API allows you to remotely manage the city lights. - ### Check out its awesome features: - * Turn a specific streetlight on/off πŸŒƒ - * Dim a specific streetlight 😎 - * Receive real-time information about environmental lighting conditions πŸ“ˆ - license: - name: Apache 2.0 - url: https://www.apache.org/licenses/LICENSE-2.0 -servers: - test: - url: test.mykafkacluster.org:8092 - protocol: kafka-secure - description: Test broker - security: - - saslScram: [] -defaultContentType: application/json -channels: - smartylighting.streetlights.1.0.event.{streetlightId}.lighting.measured: - description: The topic on which measured values may be produced and consumed. - parameters: - streetlightId: - $ref: '#/components/parameters/streetlightId' - publish: - summary: Inform about environmental lighting conditions of a particular streetlight. - operationId: receiveLightMeasurement - traits: - - $ref: '#/components/operationTraits/kafka' - message: - $ref: '#/components/messages/lightMeasured' - smartylighting.streetlights.1.0.action.{streetlightId}.turn.on: - parameters: - streetlightId: - $ref: '#/components/parameters/streetlightId' - subscribe: - operationId: turnOn - traits: - - $ref: '#/components/operationTraits/kafka' - message: - $ref: '#/components/messages/turnOnOff' - smartylighting.streetlights.1.0.action.{streetlightId}.turn.off: - parameters: - streetlightId: - $ref: '#/components/parameters/streetlightId' - subscribe: - operationId: turnOff - traits: - - $ref: '#/components/operationTraits/kafka' - message: - $ref: '#/components/messages/turnOnOff' - smartylighting.streetlights.1.0.action.{streetlightId}.dim: - parameters: - streetlightId: - $ref: '#/components/parameters/streetlightId' - subscribe: - operationId: dimLight - traits: - - $ref: '#/components/operationTraits/kafka' - message: - $ref: '#/components/messages/dimLight' -components: - messages: - lightMeasured: - name: lightMeasured - title: Light measured - summary: Inform about environmental lighting conditions of a particular streetlight. - contentType: application/json - traits: - - $ref: '#/components/messageTraits/commonHeaders' - payload: - $ref: "#/components/schemas/lightMeasuredPayload" - turnOnOff: - name: turnOnOff - title: Turn on/off - summary: Command a particular streetlight to turn the lights on or off. - traits: - - $ref: '#/components/messageTraits/commonHeaders' - payload: - $ref: "#/components/schemas/turnOnOffPayload" - dimLight: - name: dimLight - title: Dim light - summary: Command a particular streetlight to dim the lights. - traits: - - $ref: '#/components/messageTraits/commonHeaders' - payload: - $ref: "#/components/schemas/dimLightPayload" - schemas: - lightMeasuredPayload: - type: object - properties: - lumens: - type: integer - minimum: 0 - description: Light intensity measured in lumens. - sentAt: - $ref: "#/components/schemas/sentAt" - turnOnOffPayload: - type: object - properties: - command: - type: string - enum: - - on - - off - description: Whether to turn on or off the light. - sentAt: - $ref: "#/components/schemas/sentAt" - dimLightPayload: - type: object - properties: - percentage: - type: integer - description: Percentage to which the light should be dimmed to. - minimum: 0 - maximum: 100 - sentAt: - $ref: "#/components/schemas/sentAt" - sentAt: - type: string - format: date-time - description: Date and time when the message was sent. - securitySchemes: - saslScram: - type: scramSha256 - description: Provide your username and password for SASL/SCRAM authentication - parameters: - streetlightId: - description: The ID of the streetlight. - schema: - type: string - messageTraits: - commonHeaders: - headers: - type: object - properties: - my-app-header: - type: integer - minimum: 0 - maximum: 100 - operationTraits: - kafka: - bindings: - kafka: - clientId: my-app-id diff --git a/asyncapi_docs/rpc_client.yaml b/asyncapi_docs/rpc_client.yaml deleted file mode 100644 index 528b7ffa..00000000 --- a/asyncapi_docs/rpc_client.yaml +++ /dev/null @@ -1,69 +0,0 @@ -asyncapi: '2.6.0' -id: 'urn:example:rpcclient' -defaultContentType: application/json - -info: - title: RPC Client Example - description: This example demonstrates how to define an RPC client. - version: '1.0.0' - -servers: - production: - url: rabbitmq.example.org - protocol: amqp - -channels: - '{queue}': - parameters: - queue: - schema: - type: string - pattern: '^amq\\.gen\\-.+$' - bindings: - amqp: - is: queue - queue: - exclusive: true - publish: - operationId: receiveSumResult - bindings: - amqp: - ack: false - message: - correlationId: - location: $message.header#/correlation_id - payload: - type: object - properties: - result: - type: number - examples: - - 7 - - rpc_queue: - bindings: - amqp: - is: queue - queue: - durable: false - subscribe: - operationId: requestSum - bindings: - amqp: - ack: true - message: - bindings: - amqp: - replyTo: - type: string - correlationId: - location: $message.header#/correlation_id - payload: - type: object - properties: - numbers: - type: array - items: - type: number - examples: - - [4,3] \ No newline at end of file diff --git a/asyncapi_docs/rpc_server.yaml b/asyncapi_docs/rpc_server.yaml deleted file mode 100644 index 5080c599..00000000 --- a/asyncapi_docs/rpc_server.yaml +++ /dev/null @@ -1,66 +0,0 @@ -asyncapi: '2.6.0' -id: 'urn:example:rpcserver' -defaultContentType: application/json - -info: - title: RPC Server Example - description: This example demonstrates how to define an RPC server. - version: '1.0.0' - -servers: - production: - url: rabbitmq.example.org - protocol: amqp - -channels: - '{queue}': - parameters: - queue: - schema: - type: string - pattern: '^amq\\.gen\\-.+$' - bindings: - amqp: - is: queue - queue: - exclusive: true - subscribe: - operationId: sendSumResult - bindings: - amqp: - ack: true - message: - correlationId: - location: $message.header#/correlation_id - payload: - type: object - properties: - result: - type: number - examples: - - 7 - - rpc_queue: - bindings: - amqp: - is: queue - queue: - durable: false - publish: - operationId: sum - message: - bindings: - amqp: - replyTo: - type: string - correlationId: - location: $message.header#/correlation_id - payload: - type: object - properties: - numbers: - type: array - items: - type: number - examples: - - [4,3] \ No newline at end of file diff --git a/asyncapi_docs/title_min.yaml b/asyncapi_docs/title_min.yaml deleted file mode 100644 index 62eac130..00000000 --- a/asyncapi_docs/title_min.yaml +++ /dev/null @@ -1,24 +0,0 @@ -asyncapi: '2.6.0' - -info: - title: Streetlights Kafka API - version: '1.0.0' - description: | - The Smartylighting Streetlights API allows you to remotely manage the city lights. - ### Check out its awesome features: - * Turn a specific streetlight on/off πŸŒƒ - * Dim a specific streetlight 😎 - * Receive real-time information about environmental lighting conditions πŸ“ˆ - license: - name: Apache 2.0 - url: https://www.apache.org/licenses/LICENSE-2.0 - -servers: - test: - url: test.mykafkacluster.org:8092 - protocol: kafka-secure - description: Test broker - security: - - saslScram: [] - -defaultContentType: application/json \ No newline at end of file diff --git a/docs/docs/assets/img/docs-html-short.png b/docs/docs/assets/img/docs-html-short.png new file mode 100644 index 0000000000000000000000000000000000000000..464e501afcbedabe400148ac9f3f2e75e0f5f8a2 GIT binary patch literal 249445 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

m65{?hlat4r$1qRBm#c{87T^I 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�g!8UDf|)JC>bJa6x%_)pgshtQyPq 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 docs_src/quickstart/documentation/example.py !} +``` + +## YAML схСма + +Для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠ³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ **AsyncAPI** ΡΠΏΠ΅Ρ†ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΡŽ вашСго ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅ `.yaml` ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΡƒΡŽ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ: + +

+ +Π’Π΅ΠΏΠ΅Ρ€ΡŒ Ρƒ вас Π΅ΡΡ‚ΡŒ схСма вашСго ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°: Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π΅Π΅ для Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ² Π½Π° любом языкС с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΠ²ΡƒΡŽΡ‰ΠΈΡ… инструмСнтов [**AsyncAPI**]({{ urls.asyncapi }}/tools/generator){.external-link target="_blank"} + +???- example "Asyncapi.yaml" + ```yaml + {!> docs_src/quickstart/documentation/example.yaml !} + ``` + +## Онлайн докумСнтация + +Π’Π°ΠΊΠΆΠ΅, **Propan** позволяСт Π²Π°ΠΌ Ρ€Π°Π·Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒ HTML-прСдставлСниС вашСй Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ + +!!! warning "" + Онлайн прСдставлСни Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ Π½Π΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π±Π΅Π· ΠΈΠ½Ρ‚Π΅Ρ€Π½Π΅Ρ‚-соСдинСния, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ для Π΅Π΅ отобраТСния ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ **CDN** зависимости. + +
+```console +$ propan docs serve example:app +``` +
+ +Π’Π°ΠΊ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ всСм внСшним потрСбитСлям доступ ΠΊ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ вашСго ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° Π±Π΅Π· Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… Π·Π°Ρ‚Ρ€Π°Ρ‚ Π½Π° Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ. + +???- example "HTML page" + ![HTML-page](../../assets/img/docs-html.png) + +!!! tip + **Propan** Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Ρ…ΠΎΡΡ‚ΠΈΡ‚ΡŒ `asyncapi.yaml` Ρ„Π°ΠΉΠ»Ρ‹. + + ```console + propan docs serve asyncapi.yaml + ``` + Π­Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ Ссли Π²Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ Ρ€Π°ΡΡˆΠΈΡ€ΠΈΡ‚ΡŒ автоматичСски ΡΠ³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Π½Π½ΡƒΡŽ **AsyncAPI** Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡŽ: Π²Ρ‹ просто Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ Ρ„Π°ΠΉΠ», Π΄ΠΎΡ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚Π΅ Π΅Π³ΠΎ ΠΈ хоститС! + +ΠŸΡ€ΠΈ использовании ΠΎΠ½Π»Π°ΠΉΠ½ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ Π²Ρ‹ Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡΠΊΠ°Ρ‡Π°Ρ‚ΡŒ Π΅Π΅ ΠΏΠΎ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌ путям: + +* `/asyncapi.json` - **JSON** схСма (доступно ΠΏΡ€ΠΈ хостингС прилоТСния) +* `/asyncapi.yaml` - **YAML** схСма (доступна ΠΊΠ°ΠΊ для прилоТСния, Ρ‚Π°ΠΊ ΠΈ для Ρ„Π°ΠΉΠ»Π°) + +### FastAPI Plugin + +ΠŸΡ€ΠΈ использовании **Propan** Π² качСствС Ρ€ΠΎΡƒΡ‚Π΅Ρ€Π° для **FastAPI**, Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊ автоматичСски рСгистрируСт эндпоинты для хостинга **AsyncAPI** Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ Π² вашС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ со ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌΠΈ значСниями ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ: + +```python linenums='1' +{!> docs_src/quickstart/documentation/fastapi.py !} +``` + +## БобствСнный хостинг + +Для хостинга Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ **Propan** ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ **FastAPI** + **uvicorn**. +Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Π²Ρ‹ Π·Π°Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π»ΠΎΠ³ΠΈΠΊΡƒ ΠΏΠΎΠΊΠ°Π·Π° Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ: ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΡ‚ΡŒ ΠΏΡ€Π°Π²Π° доступа, ΠΊΠ°ΡΡ‚ΠΎΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚ Π² заивисмоти ΠΎΡ‚ ΠΏΡ€Π°Π² доступа, Π²ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡŽ Π² своС frontend-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΈ Ρ‚Π΄. +Для это Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ ΡΠ³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ `json`/`yaml`/`html` Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π² собствСнном сСрвисС. + +```python linenums='1' hl_lines="9-12" +{!> docs_src/quickstart/documentation/custom_schema.py !} +``` diff --git a/docs/docs/ru/index.md b/docs/docs/ru/index.md index 86cadbf2..770055d2 100644 --- a/docs/docs/ru/index.md +++ b/docs/docs/ru/index.md @@ -51,6 +51,7 @@ * ΠŸΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ совмСстимый с Π»ΡŽΠ±Ρ‹ΠΌ Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠΎΠΌ способ ΡƒΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ ΠΎΠΊΡ€ΡƒΠΆΠ΅Π½ΠΈΠ΅ΠΌ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° * *hot reloading* ΠΏΡ€ΠΈ измСнСниях Π² ΠΊΠΎΠ΄Π΅ * Π“ΠΎΡ‚ΠΎΠ²Ρ‹Π΅ ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° +* [**ДокумСнтация**](getting_started/9_documentation/): **Propan** автоматичСски Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΈ прСдставляСт ΠΈΠ½Ρ‚Π΅Ρ€Π°ΠΊΡ‚ΠΈΠ²Π½ΡƒΡŽ [**AsyncAPI**]({{ urls.asyncapi }}){target="_blank"} Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡŽ для вашСго ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° * [**Π’Π΅ΡΡ‚ΠΈΡ€ΡƒΠ΅ΠΌΠΎΡΡ‚ΡŒ**](getting_started/7_testing): **Propan** позволяСт Ρ‚Π΅ΡΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ вашС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π±Π΅Π· Π²Π½Π΅ΡˆΠ½ΠΈΡ… зависимостСй: Π²Π°ΠΌ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ ΠΏΠΎΠ΄Π½ΠΈΠΌΠ°Ρ‚ΡŒ Π±Ρ€ΠΎΠΊΠ΅Ρ€ сообщСний, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ! --- diff --git a/docs/docs_src/quickstart/documentation/custom_schema.py b/docs/docs_src/quickstart/documentation/custom_schema.py new file mode 100644 index 00000000..bddb93a9 --- /dev/null +++ b/docs/docs_src/quickstart/documentation/custom_schema.py @@ -0,0 +1,12 @@ +from propan import PropanApp, RabbitBroker +from propan.asyncapi.main import AsyncAPISchema +from propan.cli.docs.gen import gen_app_schema_json, gen_app_schema_yaml, get_app_schema +from propan.cli.docs.serve import get_asyncapi_html + +broker = RabbitBroker() +app = PropanApp(broker) + +schema: AsyncAPISchema = get_app_schema(app) +json_schema = gen_app_schema_json(app) +yaml_schema = gen_app_schema_yaml(app) +html = get_asyncapi_html(yaml_schema) \ No newline at end of file diff --git a/docs/docs_src/quickstart/documentation/example.py b/docs/docs_src/quickstart/documentation/example.py new file mode 100644 index 00000000..77acde85 --- /dev/null +++ b/docs/docs_src/quickstart/documentation/example.py @@ -0,0 +1,23 @@ +from propan import PropanApp, RabbitBroker +from propan.brokers.rabbit import RabbitQueue, RabbitExchange, ExchangeType + +broker = RabbitBroker() +app = PropanApp( + broker=broker, + title="Smartylighting Streetlights Propan API", + version="1.0.0", + description=""" + The Smartylighting Streetlights API. + ### Check out its awesome features: + * Turn a specific streetlight on/off πŸŒƒ + * Receive real-time information about environmental πŸ“ˆ + """ +) + +@broker.handle( + queue=RabbitQueue("*.info", durable=True), + exchange=RabbitExchange("logs", durable=True, type=ExchangeType.TOPIC) +) +async def handle_logs(level: int, message: str = ""): + """Handle all environmental events""" + ... diff --git a/docs/docs_src/quickstart/documentation/example.yaml b/docs/docs_src/quickstart/documentation/example.yaml new file mode 100644 index 00000000..1034044b --- /dev/null +++ b/docs/docs_src/quickstart/documentation/example.yaml @@ -0,0 +1,67 @@ +asyncapi: 2.6.0 +defaultContentType: application/json +info: + title: Smartylighting Streetlights Propan API + version: 1.0.0 + description: "\n The Smartylighting Streetlights API.\n ### Check out its\ + \ awesome features:\n * Turn a specific streetlight on/off \U0001F303\n \ + \ * Receive real-time information about environmental \U0001F4C8\n " +servers: + dev: + url: amqp://guest:guest@localhost:5672/ + protocol: amqp + protocolVersion: 0.9.1 +channels: + HandleLogs: + servers: + - dev + bindings: + amqp: + is: routingKey + bindingVersion: 0.2.0 + queue: + name: '*.info' + durable: true + exclusive: false + autoDelete: false + vhost: / + exchange: + name: logs + type: topic + durable: true + autoDelete: false + vhost: / + subscribe: + description: Handle all environmental events + bindings: + amqp: + cc: '*.info' + ack: true + bindingVersion: 0.2.0 + message: + $ref: '#/components/messages/HandleLogsMessage' +components: + messages: + HandleLogsMessage: + title: HandleLogsMessage + correlationId: + location: $message.header#/correlation_id + payload: + $ref: '#/components/schemas/HandleLogsPayload' + schemas: + HandleLogsPayload: + title: HandleLogsPayload + type: object + properties: + level: + title: Level + type: integer + message: + title: Message + default: '' + type: string + required: + - level + example: + level: 4015 + message: evwWheCeRIGhHEHYxKSJ diff --git a/docs/docs_src/quickstart/documentation/fastapi.py b/docs/docs_src/quickstart/documentation/fastapi.py new file mode 100644 index 00000000..98c1cf49 --- /dev/null +++ b/docs/docs_src/quickstart/documentation/fastapi.py @@ -0,0 +1,6 @@ +from propan.fastapi import RabbitRouter + +router = RabbitRouter( + schema_url="/asyncapi", + include_in_schema=True, +) \ No newline at end of file diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index e798912b..845f7851 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -104,6 +104,7 @@ extra: nats_py: https://github.com/nats-io/nats.py pydantic: https://docs.pydantic.dev/ pytest: https://docs.pytest.org/en/latest/ + asyncapi: https://www.asyncapi.com/ social: - icon: fontawesome/brands/github-alt link: https://github.com/lancetnik/propan @@ -128,6 +129,7 @@ nav: - Lifespan: getting_started/6_lifespans.md - Testing: getting_started/7_testing.md - Logging: getting_started/8_logging.md + - Documentation: getting_started/9_documentation.md - RabbitMQ: - Routing: rabbit/1_routing.md - Exchanges: rabbit/2_exchanges.md diff --git a/examples/http_frameworks_integrations/native_fastapi.py b/examples/http_frameworks_integrations/native_fastapi.py index 3bfebdcd..366cfaa1 100644 --- a/examples/http_frameworks_integrations/native_fastapi.py +++ b/examples/http_frameworks_integrations/native_fastapi.py @@ -3,10 +3,10 @@ from propan.fastapi import RabbitRouter -app = FastAPI() - router = RabbitRouter("amqp://guest:guest@localhost:5672") +app = FastAPI(lifespan=router.lifespan_context) + class Incoming(BaseModel): m: dict diff --git a/propan/brokers/_model/broker_usecase.py b/propan/brokers/_model/broker_usecase.py index c7800609..bda310a2 100644 --- a/propan/brokers/_model/broker_usecase.py +++ b/propan/brokers/_model/broker_usecase.py @@ -179,6 +179,7 @@ def handle( parse_message: CustomParser[MsgType] = None, description: str = "", _raw: bool = False, + _get_dependant: Callable[[Callable[..., Any]], Dependant] = get_dependant, **broker_kwargs: Any, ) -> HandlerWrapper: raise NotImplementedError() @@ -223,15 +224,29 @@ def _wrap_handler( decode_message: CustomDecoder[MsgType] = None, parse_message: CustomParser[MsgType] = None, _raw: bool = False, + _get_dependant: Callable[..., Dependant] = get_dependant, **broker_log_context_kwargs: Any, ) -> Tuple[Callable[[MsgType, bool], Awaitable[Optional[T]]], Dependant]: - dependant = get_dependant(path="", call=func) + dependant = _get_dependant(path="", call=func) extra = [ - get_dependant(path="", call=d.dependency) + _get_dependant(path="", call=d.dependency) for d in chain(extra_dependencies, self.dependencies) ] dependant.dependencies.extend(extra) + if getattr(dependant, "flat_params", None) is None: # handle FastAPI Dependant + params = dependant.path_params + dependant.body_params + + for d in dependant.dependencies: + params.extend(d.path_params + d.body_params) + + params_unique = [] + for p in params: + if p not in params_unique: + params_unique.append(p) + + dependant.flat_params = params_unique + f = cast(Callable[..., Awaitable[T]], to_async(func)) if self._is_apply_types is True: diff --git a/propan/brokers/_model/schemas.py b/propan/brokers/_model/schemas.py index c4d3d62a..9a60f64a 100644 --- a/propan/brokers/_model/schemas.py +++ b/propan/brokers/_model/schemas.py @@ -42,7 +42,7 @@ def get_message_object(self) -> Tuple[str, AnyDict, Optional[AnyDict]]: dependant = self.dependant - if dependant.return_field: + if getattr(dependant, "return_field", None) is not None: return_field = dependant.return_field if issubclass(return_field.type_, BaseModel): diff --git a/propan/cli/docs/app.py b/propan/cli/docs/app.py index 2fbd2383..2fa471de 100644 --- a/propan/cli/docs/app.py +++ b/propan/cli/docs/app.py @@ -30,7 +30,7 @@ def gen( help="generated document filename", ), ) -> None: - """Generate an AsyncAPI schema.yaml for your project""" + """Generate an AsyncAPI scheme.yaml for your project""" current_dir = Path.cwd() generated_filepath = current_dir / filename diff --git a/propan/cli/docs/gen.py b/propan/cli/docs/gen.py index bdd91dfb..ae6c1fb0 100644 --- a/propan/cli/docs/gen.py +++ b/propan/cli/docs/gen.py @@ -23,7 +23,7 @@ def generate_doc_file(app: PropanApp, filename: Path) -> None: json_schema = schema_to_json(schema) yaml_schema = json_schema_to_yaml(json_schema) filename.write_text(yaml_schema) - typer.echo(f"Your project AsyncAPI schema was placed to `{filename}`") + typer.echo(f"Your project AsyncAPI scheme was placed to `{filename}`") def gen_app_schema_yaml(app: PropanApp) -> str: @@ -108,8 +108,8 @@ def _get_app_info(app: PropanApp) -> AsyncAPIInfo: title=app.title, version=app.version, description=app.description, - license=app.license, - contact=app.contact, + license=getattr(app, "license", None), + contact=getattr(app, "contact", None), ) diff --git a/propan/cli/docs/serve.py b/propan/cli/docs/serve.py index a5c440e8..d2e472e7 100644 --- a/propan/cli/docs/serve.py +++ b/propan/cli/docs/serve.py @@ -1,5 +1,5 @@ import json -from typing import Any, Dict, Optional, Union, cast +from typing import Any, Callable, Dict, Optional, Union from propan.asyncapi import AsyncAPISchema from propan.cli.docs.gen import schema_to_json @@ -16,48 +16,21 @@ def serve_docs( import uvicorn from fastapi import FastAPI - from fastapi.responses import HTMLResponse, Response app = FastAPI() - @app.get("/", response_class=HTMLResponse) - def read_items( - sidebar: bool = True, - info: bool = True, - servers: bool = True, - operations: bool = True, - messages: bool = True, - schemas: bool = True, - errors: bool = True, - expandMessageExamples: bool = True, - ) -> str: - return get_asyncapi_html( - schema, - sidebar=sidebar, - info=info, - servers=servers, - operations=operations, - messages=messages, - schemas=schemas, - errors=errors, - expand_message_examples=expandMessageExamples, - title=raw_schema.info.title if raw_schema else "Propan", - ) + app.get("/")(asyncapi_html_endpoint(schema, raw_schema)) if raw_schema is not None: + app.get("/asyncapi.json")(download_json_endpoint(raw_schema)) - @app.get("/asyncapi.json") - def download_json() -> Response: - return Response( - content=json.dumps( - schema_to_json(cast(AsyncAPISchema, raw_schema)), indent=4 - ), - headers={ - "Content-Type": "application/octet-stream", - }, - ) + app.get("/asyncapi.yaml")(download_yaml_endpoint(schema)) + uvicorn.run(app, host=host, port=port) + + +def download_yaml_endpoint(schema: str) -> Callable[[], Any]: + from fastapi.responses import Response - @app.get("/asyncapi.yaml") def download_yaml() -> Response: return Response( content=schema, @@ -66,7 +39,57 @@ def download_yaml() -> Response: }, ) - uvicorn.run(app, host=host, port=port) + return download_yaml + + +def download_json_endpoint(raw_schema: AsyncAPISchema) -> Callable[[], Any]: + from fastapi.responses import Response + + def download_json() -> Response: + return Response( + content=json.dumps( + schema_to_json(raw_schema), + indent=4, + ), + headers={ + "Content-Type": "application/octet-stream", + }, + ) + + return download_json + + +def asyncapi_html_endpoint( + schema: str, raw_schema: Optional[AsyncAPISchema] = None +) -> Callable[[], Any]: + from fastapi.responses import HTMLResponse + + def asyncapi( + sidebar: bool = True, + info: bool = True, + servers: bool = True, + operations: bool = True, + messages: bool = True, + schemas: bool = True, + errors: bool = True, + expandMessageExamples: bool = True, + ) -> HTMLResponse: + return HTMLResponse( + content=get_asyncapi_html( + schema, + sidebar=sidebar, + info=info, + servers=servers, + operations=operations, + messages=messages, + schemas=schemas, + errors=errors, + expand_message_examples=expandMessageExamples, + title=raw_schema.info.title if raw_schema else "Propan", + ) + ) + + return asyncapi def get_asyncapi_html( diff --git a/propan/cli/main.py b/propan/cli/main.py index 2c6d9762..acd9fa58 100644 --- a/propan/cli/main.py +++ b/propan/cli/main.py @@ -18,7 +18,7 @@ cli.add_typer( create_app, name="create", help="Create a new Propan project at [APPNAME] directory" ) -cli.add_typer(docs_app, name="docs", help="AsyncAPI schema commands") +cli.add_typer(docs_app, name="docs", help="AsyncAPI scheme commands") def version_callback(version: bool) -> None: diff --git a/propan/fastapi/core/route.py b/propan/fastapi/core/route.py index 1a289b9f..3d5f6021 100644 --- a/propan/fastapi/core/route.py +++ b/propan/fastapi/core/route.py @@ -1,5 +1,6 @@ import asyncio import inspect +from functools import wraps from itertools import dropwhile from typing import Any, Callable, Coroutine, Optional, Union @@ -33,15 +34,18 @@ def __init__( call=endpoint, ) - handler = PropanMessage.get_session( - self.dependant, - dependency_overrides_provider, + handler = wraps(endpoint)( + PropanMessage.get_session( + self.dependant, + dependency_overrides_provider, + ) ) broker.handle( path, *extra, _raw=True, + _get_dependant=get_dependant, # type: ignore **handle_kwargs, # type: ignore )(handler) diff --git a/propan/fastapi/core/router.py b/propan/fastapi/core/router.py index 2b441933..2017c512 100644 --- a/propan/fastapi/core/router.py +++ b/propan/fastapi/core/router.py @@ -1,3 +1,4 @@ +import json from contextlib import asynccontextmanager from enum import Enum from typing import ( @@ -13,19 +14,27 @@ Union, ) -from fastapi import APIRouter, FastAPI, params +from fastapi import APIRouter, FastAPI, Request, params from fastapi.datastructures import Default from fastapi.routing import APIRoute from fastapi.types import DecoratedCallable from fastapi.utils import generate_unique_id from starlette import routing -from starlette.responses import JSONResponse, Response +from starlette.responses import HTMLResponse, JSONResponse, Response from starlette.routing import _DefaultLifespan from starlette.types import ASGIApp, Lifespan from typing_extensions import AsyncIterator, TypeVar from propan.brokers._model import BrokerUsecase from propan.brokers._model.schemas import Queue +from propan.cli.docs.gen import ( + gen_app_schema_json, + gen_app_schema_yaml, + get_app_schema, + json_schema_to_yaml, + schema_to_json, +) +from propan.cli.docs.serve import get_asyncapi_html from propan.fastapi.core.route import PropanRoute from propan.types import AnyDict @@ -54,6 +63,7 @@ def __init__( on_shutdown: Optional[Sequence[Callable[[], Any]]] = None, deprecated: Optional[bool] = None, include_in_schema: bool = True, + schema_url: str = "/asyncapi", lifespan: Optional[Lifespan[Any]] = None, generate_unique_id_function: Callable[[APIRoute], str] = Default( generate_unique_id @@ -90,6 +100,11 @@ def __init__( on_shutdown=on_shutdown, ) + if self.include_in_schema is True: + self.get(schema_url)(serve_asyncapi_schema) + self.get(f"{schema_url}.json")(download_app_json_schema) + self.get(f"{schema_url}.yaml")(download_app_yaml_schema) + def add_api_mq_route( self, path: Union[Queue, str], @@ -134,6 +149,8 @@ def _wrap_lifespan(self, lifespan: Optional[Lifespan[Any]] = None) -> Lifespan[A async def start_broker_lifespan( app: FastAPI, ) -> AsyncIterator[Dict[str, Broker]]: + app.broker = self.broker # type: ignore + async with lifespan_context(app) as maybe_context: await self.broker.start() context = {"broker": self.broker} @@ -143,3 +160,54 @@ async def start_broker_lifespan( await self.broker.close() return start_broker_lifespan + + +def download_app_json_schema(r: Request) -> Response: + return Response( + content=json.dumps( + gen_app_schema_json(r.app), + indent=4, + ), + headers={ + "Content-Type": "application/octet-stream", + }, + ) + + +def download_app_yaml_schema(r: Request) -> Response: + return Response( + content=gen_app_schema_yaml(r.app), + headers={ + "Content-Type": "application/octet-stream", + }, + ) + + +def serve_asyncapi_schema( + r: Request, + sidebar: bool = True, + info: bool = True, + servers: bool = True, + operations: bool = True, + messages: bool = True, + schemas: bool = True, + errors: bool = True, + expandMessageExamples: bool = True, +) -> HTMLResponse: + raw_schema = get_app_schema(r.app) + json_schema = schema_to_json(raw_schema) + schema = json_schema_to_yaml(json_schema) + return HTMLResponse( + content=get_asyncapi_html( + schema, + sidebar=sidebar, + info=info, + servers=servers, + operations=operations, + messages=messages, + schemas=schemas, + errors=errors, + expand_message_examples=expandMessageExamples, + title=raw_schema.info.title if raw_schema else "Propan", + ) + ) diff --git a/propan/fastapi/kafka/router.pyi b/propan/fastapi/kafka/router.pyi index 626f1092..8d7d60c1 100644 --- a/propan/fastapi/kafka/router.pyi +++ b/propan/fastapi/kafka/router.pyi @@ -6,6 +6,7 @@ from typing import Any, Callable, Dict, List, Optional, Sequence, Type, Union from aiokafka.abc import AbstractTokenProvider from aiokafka.producer.producer import _missing +from aiokafka.structs import ConsumerRecord from fastapi import params from fastapi.datastructures import Default from fastapi.routing import APIRoute @@ -20,6 +21,7 @@ from typing_extensions import Literal, TypeVar from propan import KafkaBroker from propan.__about__ import __version__ +from propan.brokers._model.broker_usecase import CustomDecoder, CustomParser from propan.fastapi.core import PropanRouter from propan.log import access_logger from propan.types import AnyCallable @@ -92,10 +94,14 @@ class KafkaRouter(PropanRouter[KafkaBroker]): ), loop: Optional[AbstractEventLoop] = None, # Broker kwargs + schema_url: str = "/asyncapi", logger: Optional[logging.Logger] = access_logger, log_level: int = logging.INFO, log_fmt: Optional[str] = None, apply_types: bool = True, + decode_message: CustomDecoder[ConsumerRecord] = None, + parse_message: CustomParser[ConsumerRecord] = None, + protocol: str = "kafka", ) -> None: pass def add_api_mq_route( # type: ignore[override] @@ -131,7 +137,11 @@ class KafkaRouter(PropanRouter[KafkaBroker]): "read_uncommitted", "read_committed", ] = "read_uncommitted", + # broker kwargs retry: Union[bool, int] = False, + decode_message: CustomDecoder[ConsumerRecord] = None, + parse_message: CustomParser[ConsumerRecord] = None, + description: str = "", ) -> None: pass def event( # type: ignore[override] @@ -166,6 +176,10 @@ class KafkaRouter(PropanRouter[KafkaBroker]): "read_uncommitted", "read_committed", ] = "read_uncommitted", + # broker kwargs retry: Union[bool, int] = False, + decode_message: CustomDecoder[ConsumerRecord] = None, + parse_message: CustomParser[ConsumerRecord] = None, + description: str = "", ) -> None: pass diff --git a/propan/fastapi/nats/router.pyi b/propan/fastapi/nats/router.pyi index b52a5dca..73701451 100644 --- a/propan/fastapi/nats/router.pyi +++ b/propan/fastapi/nats/router.pyi @@ -23,11 +23,13 @@ from nats.aio.client import ( JWTCallback, SignatureCallback, ) +from nats.aio.msg import Msg from starlette import routing from starlette.responses import JSONResponse, Response from starlette.types import ASGIApp from propan import NatsBroker +from propan.brokers._model.broker_usecase import CustomDecoder, CustomParser from propan.fastapi.core.router import PropanRouter from propan.log import access_logger from propan.types import AnyCallable @@ -86,10 +88,14 @@ class NatsRouter(PropanRouter[NatsBroker]): generate_unique_id ), # Broker kwargs + schema_url: str = "/asyncapi", logger: Optional[logging.Logger] = access_logger, log_level: int = logging.INFO, log_fmt: Optional[str] = None, apply_types: bool = True, + decode_message: CustomDecoder[Msg] = None, + parse_message: CustomParser[Msg] = None, + protocol: str = "nats", ) -> None: pass def add_api_mq_route( # type: ignore[override] @@ -99,6 +105,9 @@ class NatsRouter(PropanRouter[NatsBroker]): queue: str = "", endpoint: AnyCallable, retry: Union[bool, int] = False, + decode_message: CustomDecoder[Msg] = None, + parse_message: CustomParser[Msg] = None, + description: str = "", ) -> None: pass def event( # type: ignore[override] @@ -107,5 +116,8 @@ class NatsRouter(PropanRouter[NatsBroker]): *, queue: str = "", retry: Union[bool, int] = False, + decode_message: CustomDecoder[Msg] = None, + parse_message: CustomParser[Msg] = None, + description: str = "", ) -> None: pass diff --git a/propan/fastapi/rabbit/router.pyi b/propan/fastapi/rabbit/router.pyi index df667cc6..893ff8a5 100644 --- a/propan/fastapi/rabbit/router.pyi +++ b/propan/fastapi/rabbit/router.pyi @@ -4,6 +4,7 @@ from ssl import SSLContext from typing import Any, Callable, Dict, List, Optional, Sequence, Type, Union import aio_pika +from aio_pika.message import IncomingMessage from fastapi import params from fastapi.datastructures import Default from fastapi.routing import APIRoute @@ -14,6 +15,7 @@ from starlette.responses import JSONResponse, Response from starlette.types import ASGIApp from propan import RabbitBroker +from propan.brokers._model.broker_usecase import CustomDecoder, CustomParser from propan.brokers.rabbit import RabbitExchange, RabbitQueue from propan.fastapi.core import PropanRouter from propan.log import access_logger @@ -57,6 +59,11 @@ class RabbitRouter(PropanRouter[RabbitBroker]): log_fmt: Optional[str] = None, apply_types: bool = True, consumers: Optional[int] = None, + decode_message: CustomDecoder[IncomingMessage] = None, + parse_message: CustomParser[IncomingMessage] = None, + schema_url: str = "/asyncapi", + protocol: str = "amqp", + protocol_version: str = "0.9.1", ) -> None: pass def add_api_mq_route( # type: ignore[override] @@ -66,6 +73,9 @@ class RabbitRouter(PropanRouter[RabbitBroker]): endpoint: AnyCallable, exchange: Union[str, RabbitExchange, None] = None, retry: Union[bool, int] = False, + decode_message: CustomDecoder[IncomingMessage] = None, + parse_message: CustomParser[IncomingMessage] = None, + description: str = "", ) -> None: pass def event( # type: ignore[override] @@ -74,5 +84,8 @@ class RabbitRouter(PropanRouter[RabbitBroker]): *, exchange: Union[str, RabbitExchange, None] = None, retry: Union[bool, int] = False, + decode_message: CustomDecoder[IncomingMessage] = None, + parse_message: CustomParser[IncomingMessage] = None, + description: str = "", ) -> None: pass diff --git a/propan/fastapi/redis/router.pyi b/propan/fastapi/redis/router.pyi index 835b27a7..7bbb16be 100644 --- a/propan/fastapi/redis/router.pyi +++ b/propan/fastapi/redis/router.pyi @@ -12,9 +12,10 @@ from starlette.responses import JSONResponse, Response from starlette.types import ASGIApp from propan import RedisBroker +from propan.brokers._model.broker_usecase import CustomDecoder, CustomParser from propan.fastapi.core.router import PropanRouter from propan.log import access_logger -from propan.types import AnyCallable +from propan.types import AnyCallable, AnyDict class RedisRouter(PropanRouter[RedisBroker]): def __init__( @@ -60,10 +61,14 @@ class RedisRouter(PropanRouter[RedisBroker]): generate_unique_id ), # Broker kwargs + schema_url: str = "/asyncapi", logger: Optional[logging.Logger] = access_logger, log_level: int = logging.INFO, log_fmt: Optional[str] = None, apply_types: bool = True, + decode_message: CustomDecoder[AnyDict] = None, + parse_message: CustomParser[AnyDict] = None, + protocol: str = "redis", ) -> None: pass def add_api_mq_route( # type: ignore[override] @@ -72,6 +77,9 @@ class RedisRouter(PropanRouter[RedisBroker]): *, endpoint: AnyCallable, pattern: bool = False, + decode_message: CustomDecoder[AnyDict] = None, + parse_message: CustomParser[AnyDict] = None, + description: str = "", ) -> None: pass def event( # type: ignore[override] @@ -79,5 +87,8 @@ class RedisRouter(PropanRouter[RedisBroker]): channel: str, *, pattern: bool = False, + decode_message: CustomDecoder[AnyDict] = None, + parse_message: CustomParser[AnyDict] = None, + description: str = "", ) -> None: pass diff --git a/propan/fastapi/sqs/router.pyi b/propan/fastapi/sqs/router.pyi index a9d3e17a..f289e541 100644 --- a/propan/fastapi/sqs/router.pyi +++ b/propan/fastapi/sqs/router.pyi @@ -12,10 +12,11 @@ from starlette.responses import JSONResponse, Response from starlette.types import ASGIApp from propan import SQSBroker +from propan.brokers._model.broker_usecase import CustomDecoder, CustomParser from propan.brokers.sqs.schema import SQSQueue from propan.fastapi.core.router import PropanRouter from propan.log import access_logger -from propan.types import AnyCallable +from propan.types import AnyCallable, AnyDict class SQSRouter(PropanRouter[SQSBroker]): def __init__( @@ -50,10 +51,14 @@ class SQSRouter(PropanRouter[SQSBroker]): generate_unique_id ), # Broker kwargs + schema_url: str = "/asyncapi", logger: Optional[logging.Logger] = access_logger, log_level: int = logging.INFO, log_fmt: Optional[str] = None, apply_types: bool = True, + decode_message: CustomDecoder[AnyDict] = None, + parse_message: CustomParser[AnyDict] = None, + protocol: str = "sqs", ) -> None: pass def add_api_mq_route( # type: ignore[override] @@ -68,6 +73,9 @@ class SQSRouter(PropanRouter[SQSBroker]): visibility_timeout: int = 0, retry: Union[bool, int] = False, endpoint: AnyCallable, + decode_message: CustomDecoder[AnyDict] = None, + parse_message: CustomParser[AnyDict] = None, + description: str = "", ) -> None: pass def event( # type: ignore[override] @@ -81,5 +89,8 @@ class SQSRouter(PropanRouter[SQSBroker]): request_attempt_id: Optional[str] = None, visibility_timeout: int = 0, retry: Union[bool, int] = False, + decode_message: CustomDecoder[AnyDict] = None, + parse_message: CustomParser[AnyDict] = None, + description: str = "", ) -> None: pass diff --git a/tests/brokers/base/test_pushback.py b/tests/brokers/base/test_pushback.py index 0bfd74a0..13e857c0 100644 --- a/tests/brokers/base/test_pushback.py +++ b/tests/brokers/base/test_pushback.py @@ -65,10 +65,10 @@ async def test_push_back_watcher(async_mock): on_max=async_mock.on_max, ) - async_mock.side_effect = Exception("Ooops!") + async_mock.side_effect = ValueError("Ooops!") while not async_mock.on_max.called: - with pytest.raises(Exception): + with pytest.raises(ValueError): async with context: await async_mock() @@ -90,10 +90,10 @@ async def test_push_endless_back_watcher(async_mock): on_max=async_mock.on_max, ) - async_mock.side_effect = Exception("Ooops!") + async_mock.side_effect = ValueError("Ooops!") while async_mock.on_error.call_count < 10: - with pytest.raises(Exception): + with pytest.raises(ValueError): async with context: await async_mock() diff --git a/tests/fastapi/case.py b/tests/fastapi/case.py index 82c221e5..1ab17f9c 100644 --- a/tests/fastapi/case.py +++ b/tests/fastapi/case.py @@ -30,7 +30,7 @@ async def hello(): async def hello2(b: int): return "2" - async with router.lifespan_context(None): + async with router.lifespan_context(app): r = await router.broker.publish( "", name, callback=True, callback_timeout=0.5 ) From 282a3b5039258df229ebc1f29b4da0d6010e651d Mon Sep 17 00:00:00 2001 From: Lancetnik Date: Tue, 13 Jun 2023 21:52:18 +0300 Subject: [PATCH 14/18] update FastAPI Plugin docs --- docs/docs/en/integrations/2_fastapi-plugin.md | 24 ++++++++++++++++++- docs/docs/ru/integrations/2_fastapi-plugin.md | 24 +++++++++++++++++-- docs/docs_src/integrations/fastapi/request.py | 3 +++ .../kafka/fastapi_after_startup.py | 16 +++++++++++++ .../nats/fastapi_after_startup.py | 16 +++++++++++++ .../rabbit/fastapi_after_startup.py | 16 +++++++++++++ .../redis/fastapi_after_startup.py | 16 +++++++++++++ .../integrations/sqs/fastapi_after_startup.py | 16 +++++++++++++ .../integrations/fastapi/after_startup.md | 24 +++++++++++++++++++ 9 files changed, 152 insertions(+), 3 deletions(-) create mode 100644 docs/docs_src/integrations/fastapi/request.py create mode 100644 docs/docs_src/integrations/kafka/fastapi_after_startup.py create mode 100644 docs/docs_src/integrations/nats/fastapi_after_startup.py create mode 100644 docs/docs_src/integrations/rabbit/fastapi_after_startup.py create mode 100644 docs/docs_src/integrations/redis/fastapi_after_startup.py create mode 100644 docs/docs_src/integrations/sqs/fastapi_after_startup.py create mode 100644 docs/includes/integrations/fastapi/after_startup.md diff --git a/docs/docs/en/integrations/2_fastapi-plugin.md b/docs/docs/en/integrations/2_fastapi-plugin.md index 520d9e1c..d4230df4 100644 --- a/docs/docs/en/integrations/2_fastapi-plugin.md +++ b/docs/docs/en/integrations/2_fastapi-plugin.md @@ -1,5 +1,7 @@ # **FastAPI** Plugin +## Handle messages + **Propan** can be used as a part of **FastAPI**. Just import a **PropanRouter** you need and declare the message handler @@ -19,7 +21,7 @@ in any way convenient for you. The message header is placed in `headers`. Also, this router can be fully used as an `HttpRouter` (of which it is the inheritor). So you can use it to declare any `get`, `post`, `put` and other HTTP methods. For example, this is done at **19** line. -### Sending messages +## Sending messages Inside each router there is a broker. You can easily access it if you need to send a message to MQ. @@ -28,3 +30,23 @@ Inside each router there is a broker. You can easily access it if you need to se You can use the following `Depends` to access the broker if you want to use it at different parts of your program. {! includes/integrations/fastapi/fastapi_plugin_depends.md !} + +Or you can access broker from a **FastAPI** application state + +```python +{! docs_src/integrations/fastapi/request.py !} +``` + +## @after_startup + +The `PropanApp` application has the `after_startup` hook, which allows you to perform operations with your message broker after the connection is established. This can be extremely convenient for managing your brokers' objects and/or sending messages. This hook is also available for your **FastAPI PropanRouter** + +{! includes/integrations/fastapi/after_startup.md !} + +## Documentation + +When using **Propan** as a router for **FastAPI**, the framework automatically registers endpoints for hosting **AsyncAPI** documentation into your application with the following default values: + +```python linenums='1' +{!> docs_src/quickstart/documentation/fastapi.py !} +``` diff --git a/docs/docs/ru/integrations/2_fastapi-plugin.md b/docs/docs/ru/integrations/2_fastapi-plugin.md index a0418c67..b52bbc72 100644 --- a/docs/docs/ru/integrations/2_fastapi-plugin.md +++ b/docs/docs/ru/integrations/2_fastapi-plugin.md @@ -1,6 +1,6 @@ # **FastAPI** Plugin -### ΠŸΡ€ΠΈΠ΅ΠΌ сообщСний +## ΠŸΡ€ΠΈΠ΅ΠΌ сообщСний **Propan** ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΊΠ°ΠΊ полноцСнная Ρ‡Π°ΡΡ‚ΡŒ **FastAPI**. @@ -20,7 +20,7 @@ Π’Π°ΠΊΠΆΠ΅ этот Ρ€ΠΎΡƒΡ‚Π΅Ρ€ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠ»Π½ΠΎΡ†Π΅Π½Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΊΠ°ΠΊ `HttpRouter` (наслСдником ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΎΠ½ ΠΈ являСтся). ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΠ±ΡŠΡΠ²Π»ΡΡ‚ΡŒ с Π΅Π³ΠΎ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π»ΡŽΠ±Ρ‹Π΅ `get`, `post`, `put` ΠΈ ΠΏΡ€ΠΎΡ‡ΠΈΠ΅ HTTP ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹. Как Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, это сдСлано Π² строкС **19**. -### ΠžΡ‚ΠΏΡ€Π°Π²ΠΊΠ° сообщСний +## ΠžΡ‚ΠΏΡ€Π°Π²ΠΊΠ° сообщСний Π’Π½ΡƒΡ‚Ρ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Ρ€ΠΎΡƒΡ‚Π΅Ρ€Π° Π΅ΡΡ‚ΡŒ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΠ²ΡƒΡŽΡ‰ΠΈΠΉ Π±Ρ€ΠΎΠΊΠ΅Ρ€. Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π»Π΅Π³ΠΊΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΊ Π½Π΅ΠΌΡƒ доступ, Ссли Π²Π°ΠΌ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ сообщСниС Π² MQ. @@ -29,3 +29,23 @@ Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΡ„ΠΎΡ€ΠΌΠΈΡ‚ΡŒ доступ ΠΊ Π±Ρ€ΠΎΠΊΠ΅Ρ€Ρƒ Π² Π²ΠΈΠ΄Π΅ `Depends`, Ссли Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π΅Π³ΠΎ Π² Ρ€Π°Π·Π½Ρ‹Ρ… частях вашСй ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹. {! includes/integrations/fastapi/fastapi_plugin_depends.md !} + +Π›ΠΈΠ±ΠΎ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ доступ ΠΊ Π±Ρ€ΠΎΠΊΠ΅Ρ€Ρƒ ΠΈΠ· контСкста прилоТСния **FastAPI** + +```python +{! docs_src/integrations/fastapi/request.py !} +``` + +## @after_startup + +ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ `PropanApp` ΠΈΠΌΠ΅Π΅Ρ‚ Ρ…ΡƒΠΊ `after_startup`, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ позволяСт Π²Π°ΠΌ ΠΎΡΡƒΡ‰Π΅ΡΡ‚Π²Π»ΡΡ‚ΡŒ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ с вашим Π±Ρ€ΠΎΠΊΠ΅Ρ€ΠΎΠΌ сообщСний послС Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ соСдинСниС с Π½ΠΈΠΌ Π±ΡƒΠ΄Π΅Ρ‚ установлСно. Π­Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΊΡ€Π°ΠΉΠ½Π΅ ΡƒΠ΄ΠΎΠ±Π½ΠΎ для ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ вашСго Π±Ρ€ΠΎΠΊΠ΅Ρ€Π° ΠΈ/ΠΈΠ»ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ сообщСний. Π­Ρ‚ΠΎΡ‚ Ρ…ΡƒΠΊ Ρ‚Π°ΠΊΠΆΠ΅ доступСн ΠΈ для Π²Π°ΡˆΠΈΡ… **FastAPI PropanRouter** + +{! includes/integrations/fastapi/after_startup.md !} + +## ДокумСнтация + +ΠŸΡ€ΠΈ использовании **Propan** Π² качСствС Ρ€ΠΎΡƒΡ‚Π΅Ρ€Π° для **FastAPI**, Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊ автоматичСски рСгистрируСт эндпоинты для хостинга **AsyncAPI** Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ Π² вашС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ со ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌΠΈ значСниями ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ: + +```python linenums='1' +{!> docs_src/quickstart/documentation/fastapi.py !} +``` diff --git a/docs/docs_src/integrations/fastapi/request.py b/docs/docs_src/integrations/fastapi/request.py new file mode 100644 index 00000000..773473ed --- /dev/null +++ b/docs/docs_src/integrations/fastapi/request.py @@ -0,0 +1,3 @@ +@app.get("/") +def main(request: Request): + broker = request.state.broker \ No newline at end of file diff --git a/docs/docs_src/integrations/kafka/fastapi_after_startup.py b/docs/docs_src/integrations/kafka/fastapi_after_startup.py new file mode 100644 index 00000000..6d739a06 --- /dev/null +++ b/docs/docs_src/integrations/kafka/fastapi_after_startup.py @@ -0,0 +1,16 @@ +from fastapi import FastAPI +from propan.fastapi import KafkaRouter + +router = KafkaRouter("localhost:9092") + +app = FastAPI(lifespan=router.lifespan_context) + +@router.after_startup +def do_smth(app: FastAPI): + ... + +@router.after_startup +async def publish_smth(app: FastAPI): + await router.broker.publish(...) + +app.include_router(router) \ No newline at end of file diff --git a/docs/docs_src/integrations/nats/fastapi_after_startup.py b/docs/docs_src/integrations/nats/fastapi_after_startup.py new file mode 100644 index 00000000..6f88576c --- /dev/null +++ b/docs/docs_src/integrations/nats/fastapi_after_startup.py @@ -0,0 +1,16 @@ +from fastapi import FastAPI +from propan.fastapi import NatsRouter + +router = NatsRouter("nats://localhost:4222") + +app = FastAPI(lifespan=router.lifespan_context) + +@router.after_startup +def do_smth(app: FastAPI): + ... + +@router.after_startup +async def publish_smth(app: FastAPI): + await router.broker.publish(...) + +app.include_router(router) \ No newline at end of file diff --git a/docs/docs_src/integrations/rabbit/fastapi_after_startup.py b/docs/docs_src/integrations/rabbit/fastapi_after_startup.py new file mode 100644 index 00000000..d0692823 --- /dev/null +++ b/docs/docs_src/integrations/rabbit/fastapi_after_startup.py @@ -0,0 +1,16 @@ +from fastapi import FastAPI +from propan.fastapi import RabbitRouter + +router = RabbitRouter("amqp://guest:guest@localhost:5672") + +app = FastAPI(lifespan=router.lifespan_context) + +@router.after_startup +def do_smth(app: FastAPI): + ... + +@router.after_startup +async def publish_smth(app: FastAPI): + await router.broker.publish(...) + +app.include_router(router) \ No newline at end of file diff --git a/docs/docs_src/integrations/redis/fastapi_after_startup.py b/docs/docs_src/integrations/redis/fastapi_after_startup.py new file mode 100644 index 00000000..faa37b46 --- /dev/null +++ b/docs/docs_src/integrations/redis/fastapi_after_startup.py @@ -0,0 +1,16 @@ +from fastapi import FastAPI +from propan.fastapi import RedisRouter + +router = RedisRouter("redis://localhost:6379") + +app = FastAPI(lifespan=router.lifespan_context) + +@router.after_startup +def do_smth(app: FastAPI): + ... + +@router.after_startup +async def publish_smth(app: FastAPI): + await router.broker.publish(...) + +app.include_router(router) \ No newline at end of file diff --git a/docs/docs_src/integrations/sqs/fastapi_after_startup.py b/docs/docs_src/integrations/sqs/fastapi_after_startup.py new file mode 100644 index 00000000..b3ee675d --- /dev/null +++ b/docs/docs_src/integrations/sqs/fastapi_after_startup.py @@ -0,0 +1,16 @@ +from fastapi import FastAPI +from propan.fastapi import SQSRouter + +router = SQSRouter("http://localhost:9324") + +app = FastAPI(lifespan=router.lifespan_context) + +@router.after_startup +def do_smth(app: FastAPI): + ... + +@router.after_startup +async def publish_smth(app: FastAPI): + await router.broker.publish(...) + +app.include_router(router) \ No newline at end of file diff --git a/docs/includes/integrations/fastapi/after_startup.md b/docs/includes/integrations/fastapi/after_startup.md new file mode 100644 index 00000000..56d1b829 --- /dev/null +++ b/docs/includes/integrations/fastapi/after_startup.md @@ -0,0 +1,24 @@ +=== "Redis" + ```python linenums="1" hl_lines="8 12" + {!> docs_src/integrations/redis/fastapi_after_startup.py!} + ``` + +=== "RabbitMQ" + ```python linenums="1" hl_lines="8 12" + {!> docs_src/integrations/rabbit/fastapi_after_startup.py!} + ``` + +=== "Kafka" + ```python linenums="1" hl_lines="8 12" + {!> docs_src/integrations/kafka/fastapi_after_startup.py!} + ``` + +=== "SQS" + ```python linenums="1" hl_lines="8 12" + {!> docs_src/integrations/sqs/fastapi_after_startup.py!} + ``` + +=== "NATS" + ```python linenums="1" hl_lines="8 12" + {!> docs_src/integrations/nats/fastapi_after_startup.py!} + ``` \ No newline at end of file From e8466e851f30bbeddc52ea15794d8c7810369c37 Mon Sep 17 00:00:00 2001 From: Lancetnik Date: Tue, 13 Jun 2023 21:56:33 +0300 Subject: [PATCH 15/18] fix hanle annotations --- propan/brokers/kafka/kafka_broker.pyi | 4 ++-- propan/brokers/rabbit/rabbit_broker.pyi | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/propan/brokers/kafka/kafka_broker.pyi b/propan/brokers/kafka/kafka_broker.pyi index b4bcc496..e336f45b 100644 --- a/propan/brokers/kafka/kafka_broker.pyi +++ b/propan/brokers/kafka/kafka_broker.pyi @@ -33,7 +33,7 @@ from propan.brokers._model.schemas import PropanMessage from propan.brokers.kafka.schemas import Handler from propan.brokers.push_back_watcher import BaseWatcher from propan.log import access_logger -from propan.types import DecodedMessage, SendableMessage, Wrapper +from propan.types import DecodedMessage, SendableMessage, HandlerWrapper T = TypeVar("T") Partition = TypeVar("Partition") @@ -190,7 +190,7 @@ class KafkaBroker( decode_message: CustomDecoder[ConsumerRecord] = None, parse_message: CustomParser[ConsumerRecord] = None, description: str = "", - ) -> Wrapper: ... + ) -> HandlerWrapper: ... @staticmethod async def _parse_message( message: ConsumerRecord, diff --git a/propan/brokers/rabbit/rabbit_broker.pyi b/propan/brokers/rabbit/rabbit_broker.pyi index 76d92790..06807aea 100644 --- a/propan/brokers/rabbit/rabbit_broker.pyi +++ b/propan/brokers/rabbit/rabbit_broker.pyi @@ -217,8 +217,9 @@ class RabbitBroker(BrokerUsecase[IncomingMessage, aio_pika.RobustConnection]): description: str = "", ) -> Callable[ [ - Callable[ - P, Union[PikaSendableMessage, Coroutine[Any, Any, PikaSendableMessage]] + Union[ + Callable[P, PikaSendableMessage], + Callable[P, Awaitable[PikaSendableMessage]], ] ], Callable[P, PikaSendableMessage], From 5eb5812d6a2a180f084c4169aaf2cf362b0cfa60 Mon Sep 17 00:00:00 2001 From: Lancetnik Date: Tue, 13 Jun 2023 22:04:47 +0300 Subject: [PATCH 16/18] add en docs docs --- .../en/getting_started/9_documentation.md | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/docs/docs/en/getting_started/9_documentation.md b/docs/docs/en/getting_started/9_documentation.md index e69de29b..d1498552 100644 --- a/docs/docs/en/getting_started/9_documentation.md +++ b/docs/docs/en/getting_started/9_documentation.md @@ -0,0 +1,87 @@ +--- +hide: + - toc +--- + +# Documenting + +**Propan** allows you not to think about the documentation of your project - it is already generated automatically in accordance with the [**AsyncAPI**]({{ urls.asyncapi }}){.external-link target="_blank"} specification ! + +## Example + +Let's look at an example. + +To begin with, we will write a small application with the following content: + +```python linenums='1' +{!> docs_src/quickstart/documentation/example.py !} +``` + +## YAML schema + +To generate the **AsyncAPI** specification of your project in the `.yaml` format use the following command: + +
+```console +$ propan docs gen example:app + +Your project AsyncAPI scheme was placed to `./asyncapi.yaml` +``` +
+ +Now you have a scheme of your project: you can use it to generate various clients in any language using an [**AsyncAPI** tools]({{ urls.asyncapi }}/tools/generator){.external-link target="_blank"}. + +???- example "Asyncapi.yaml" + ```yaml + {!> docs_src/quickstart/documentation/example.yaml !} + ``` + +## Online documentation + +Also, **Propan** allows you to host HTML representation of your documentation with the following command + +!!! warning "" + The online representation of documentation does not work without an internet connection, since **CDN** dependencies are used to display it. + +
+```console +$ propan docs serve example:app +``` +
+ +This way you can provide all external consumers with access to your project documentation without additional development costs. + +???- example "HTML page" + ![HTML-page](../../assets/img/docs-html.png) + +!!! tip + **Propan** can also host `asyncapi.yaml` files. + +```console +propan docs serve asyncapi.yaml +``` + +This can be useful if you want to extend the automatically generated **AsyncAPI** documentation: you just generate a file, modify and host it! + +When using online documentation, you can also download it using the following paths: + +* `/asyncapi.json` - **JSON** schema (available when hosting an application) +* `/asyncapi.yaml` - **YAML** schema (available for an application and a file both) + +### FastAPI Plugin + +When using **Propan** as a router for **FastAPI**, the framework automatically registers endpoints for hosting **AsyncAPI** documentation in your application with the following default values: + +```python linenums='1' +{!> docs_src/quickstart/documentation/fastapi.py !} +``` + +## Own hosting + +For hosting documentation **Propan** uses **FastAPI** + **uvicorn**. +You may want to implement the logic of displaying documentation yourself: restrict access rights, customize content regardless of access rights, embed documentation in your frontend application, and so on. +To do this, you can generate a `json`/`yaml`/`html` document yourself and use it in your own service. + +```python linenums='1' hl_lines="9-12" +{!> docs_src/quickstart/documentation/custom_schema.py !} +``` From 7487350b7de9676658ebe016df07a32611b11277 Mon Sep 17 00:00:00 2001 From: Lancetnik Date: Wed, 14 Jun 2023 20:44:10 +0300 Subject: [PATCH 17/18] add en docs --- .github/workflows/documentation.yml | 2 +- README.md | 11 ++++++ docs/docs/en/CHANGELOG.md | 24 +++++++++++++ docs/docs/en/contributing/1_todo.md | 10 +----- docs/docs/en/getting_started/1_quick-start.md | 10 ++++++ .../4_broker/3_type-casting.md | 35 +++++++++++++++---- .../5_dependency/1_di-index.md | 22 ++++++++++++ docs/docs/en/getting_started/6_lifespans.md | 2 ++ .../en/getting_started/9_documentation.md | 7 ++++ docs/docs/en/index.md | 1 + docs/docs/ru/CHANGELOG.md | 24 +++++++++++++ docs/docs/ru/contributing/1_todo.md | 11 +----- docs/docs/ru/getting_started/1_quick-start.md | 12 ++++++- .../4_broker/3_type-casting.md | 25 +++++++++++-- .../5_dependency/1_di-index.md | 29 ++++++++++++--- docs/docs/ru/getting_started/6_lifespans.md | 2 ++ .../ru/getting_started/9_documentation.md | 7 ++++ docs/mkdocs.yml | 1 + examples/grpc/gen_py_code.sh | 1 + examples/grpc/grpc_encoding.py | 25 +++++++++++++ examples/grpc/message.proto | 6 ++++ examples/grpc/requirements.txt | 1 + propan/__about__.py | 2 +- propan/annotations.py | 5 ++- propan/brokers/kafka/__init__.py | 4 +-- propan/brokers/kafka/kafka_broker.pyi | 2 +- propan/brokers/nats/__init__.py | 4 +-- propan/brokers/rabbit/__init__.py | 3 +- propan/brokers/rabbit/rabbit_broker.py | 4 +-- propan/brokers/rabbit/rabbit_broker.pyi | 1 - propan/brokers/rabbit/schemas.py | 26 +++++++------- propan/brokers/redis/__init__.py | 4 +-- propan/brokers/redis/redis_broker.py | 2 +- propan/brokers/sqs/__init__.py | 3 +- propan/test/sqs.py | 2 +- propan/utils/__init__.py | 4 ++- propan/utils/no_cast.py | 11 ++++++ pyproject.toml | 1 + 38 files changed, 282 insertions(+), 64 deletions(-) create mode 100644 examples/grpc/gen_py_code.sh create mode 100644 examples/grpc/grpc_encoding.py create mode 100644 examples/grpc/message.proto create mode 100644 examples/grpc/requirements.txt create mode 100644 propan/utils/no_cast.py diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 29092570..c3b0cd6c 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -23,6 +23,6 @@ jobs: with: key: ${{ github.ref }} path: .cache - - run: pip install mkdocs-material mkdocs-static-i18n mdx-include mkdocs-macros-plugin + - run: pip install mkdocs-material mkdocs-static-i18n mdx-include mkdocs-macros-plugin mkdocs-glightbox - working-directory: ./docs run: mkdocs gh-deploy --force diff --git a/README.md b/README.md index b7235799..ca0f7aa4 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,7 @@ It is a modern, high-level framework on top of popular specific Python brokers l * framework-independent way to manage the project environment * application code *hot reload* * robust application templates +* [**Documentation**](#project-documentation): **Propan** automatically generates and presents an interactive
**AsyncAPI** documentation for your project * **Testability**: **Propan** allows you to test your app without external dependencies: you do not have to set up a Message Broker, you can use a virtual one! ### Supported MQ brokers @@ -238,6 +239,16 @@ async def base_handler(body: dict, --- +## Project Documentation + +**Propan** automatically generates documentation for your project according to the **AsyncAPI** specification. You can work with both generated artifacts and place a Web view of your documentation on resources available to related teams. + +The availability of such documentation significantly simplifies the integration of services: you can immediately see what channels and message format the application works with. And most importantly, it doesn't cost you anything - **Propan** has already done everything for you! + +![HTML-page](../../assets/img/docs-html-short.png) + +--- + ## CLI power **Propan** has its own CLI tool that provided the following features: diff --git a/docs/docs/en/CHANGELOG.md b/docs/docs/en/CHANGELOG.md index cc9caf80..82dec10f 100644 --- a/docs/docs/en/CHANGELOG.md +++ b/docs/docs/en/CHANGELOG.md @@ -1,5 +1,29 @@ # CHANGELOG +## 2023-06-14 **0.1.3.0** AsyncAPI + +The current update adds functionality that I've been working hard on for the last month: +Now **Propan** can automatically generate and host documentation for your application +according to the [**AsyncAPI**]({{ urls.asyncapi }}){.external-link target="_blank"} specification. + +You can simply provide related teams with a link to your documentation page, where they can get acquainted with all the parameters of the server used, channels, and the format of messages consumed by your service. + +![HTML-page](../../assets/img/docs-html-short.png) + +You can learn more about this functionality in the corresponding [documentation section] (getting_started/9_documentation.md). + +Also, the ability to determine the dependencies of the broker level and consumers has been added.: + +```python +from propan import RabbitBroker, Depends + +broker = RabbitBroker(dependencies=[Depends(...)]) + +@broker.handler(..., dependencies=[Depends(...)]) +async def handler(): + ... +``` + ## 2023-06-13 **0.1.2.17** The current update is a sum of several changes and improvements released from the previous release. diff --git a/docs/docs/en/contributing/1_todo.md b/docs/docs/en/contributing/1_todo.md index 13b6c63c..83f33887 100644 --- a/docs/docs/en/contributing/1_todo.md +++ b/docs/docs/en/contributing/1_todo.md @@ -16,15 +16,7 @@ To participate in the development of documentation, go to the following [section ## Code -If you want to work a little with the code, then you have even more opportunities to prove yourself. At the moment, the priority of the project is the following tasks: - -* `PushBackWatcher` should store information about the number of message processing in the header: -this will allow you to keep a common counter for all consumers. -* Merge the arguments of the methods `__init__` and `connect` brokers for more flexible management of default values -* Coverage with `NatsBroker` tests -* Implementation of `NatsJSBroker` -* Implementation of the synchronous version of the application and brokers -* Broker implementation for `Apache Kafka' and other brokers from [plan](../../#supported-mq-brokers) +All actual tasks you can find at project [Issues](https://github.com/Lancetnik/Propan/issues){.external-link target="_blank"}. To start developing the project, go to the following [section](../2_contributing-index/). diff --git a/docs/docs/en/getting_started/1_quick-start.md b/docs/docs/en/getting_started/1_quick-start.md index 1cf0b848..8248aeed 100644 --- a/docs/docs/en/getting_started/1_quick-start.md +++ b/docs/docs/en/getting_started/1_quick-start.md @@ -56,6 +56,16 @@ and [more](../5_dependency/1_di-index). --- +## Project Documentation + +**Propan** automatically generates documentation for your project according to the [**AsyncAPI**]({{ urls.asyncapi }}){ target="_blank"} specification. You can work with both generated artifacts and place a Web view of your documentation on resources available to related teams. + +The availability of such documentation significantly simplifies the integration of services: you can immediately see what channels and message format the application works with. And most importantly, it doesn't cost you anything - **Propan** has already done everything for you! + +![HTML-page](../../assets/img/docs-html-short.png) + +--- + ## Project template Also, **Propan CLI** is able to generate a production-ready application template: diff --git a/docs/docs/en/getting_started/4_broker/3_type-casting.md b/docs/docs/en/getting_started/4_broker/3_type-casting.md index a91100fa..051fbaa2 100644 --- a/docs/docs/en/getting_started/4_broker/3_type-casting.md +++ b/docs/docs/en/getting_started/4_broker/3_type-casting.md @@ -2,13 +2,13 @@ The first argument of the function decorated by `@broker.hanle` is the decrypted body of the incoming message. -It can be of three types: +Incoming message body can be of three types: * `str` - if the message has the header `content-type: text/plain` * `dict` - if the message has the header `content-type: application/json` * `bytes` - if the message has any other header -All incoming messages will be automatically brought to this view. +Either these types can be used as an annotation, or any primitive types to which **pydantic** can cast incoming arguments (for example, `str -> float`). A few examples: @@ -19,7 +19,7 @@ A few examples: async def base_handler(body: str): ''' We are expecting a text/plain message - Messages of a different kind will trigger an error + Messages of a different kind will raise an error ''' ``` @@ -31,7 +31,7 @@ async def base_handler(body: str): async def base_handler(body: dict): ''' We are expecting an application/json message - Messages of a different kind will trigger an error + Messages of a different kind will raise an error ''' ``` @@ -42,7 +42,7 @@ async def base_handler(body: dict): async def base_handler(body: bytes): ''' We are expecting a 'raw' message - Messages of a different kind will trigger an error + Messages of a different kind will raise an error ''' ``` @@ -62,6 +62,27 @@ async def base_handler(body: Message): ''' We are expecting an application/json message Type { key: 1.0 } - Messages of a different kind will trigger an error + Messages of a different kind will raise an error ''' -``` \ No newline at end of file +``` + +### Multiple arguments + +When annotating multiple incoming arguments, the result will be equivalent to using a similar `pydantic' model. + +```python +from pydantic import BaseModel + +class Message(BaseModel): + a: int + b: float + +@broker.handle("test") +async def base_handler(a: int, b: float): +# async def base_handler(body: Message): - the same + ''' + We are expecting an application/json message + Type { a: 1, b: 1.0 } + Messages of a different kind will raise an error + ''' +``` diff --git a/docs/docs/en/getting_started/5_dependency/1_di-index.md b/docs/docs/en/getting_started/5_dependency/1_di-index.md index 0b48d064..102c8a3a 100644 --- a/docs/docs/en/getting_started/5_dependency/1_di-index.md +++ b/docs/docs/en/getting_started/5_dependency/1_di-index.md @@ -50,6 +50,28 @@ It's easy, isn't it? In the code above, we didn't use this decorator for our dependencies. However, it still applies to all functions used as dependencies. Keep this in your mind. +## Top-level dependencies + +If you don't need a dependency result you can use the following code: + +```python +@broker.handle("test") +def method(_ = Depends(...)): ... +``` + +But, using a special `handle` parameter is more suitable: + +```python +@broker.handle("test", dependencies=[Depends(...)]) +def method(): ... +``` + +Also, you are able to declare broker-level dependencies: they will be applied to all brokers' handlers. + +```python +broker = RabbitBroker(dependencies=[Depends(...)]) +``` + ## Nested dependencies Dependencies can also contain other dependencies. This works in a very predictable way: just declare diff --git a/docs/docs/en/getting_started/6_lifespans.md b/docs/docs/en/getting_started/6_lifespans.md index 06dd0316..f776ebd5 100644 --- a/docs/docs/en/getting_started/6_lifespans.md +++ b/docs/docs/en/getting_started/6_lifespans.md @@ -112,3 +112,5 @@ Command line arguments are available in all `@app.on_startup` hooks. To use them ### Broker initialization The `@app.on_startup` hooks are called **BEFORE** the broker is launched by the application. The `@app.after_shutdown` hooks are triggered **AFTER** stopping the broker. + +If you want to perform some actions **AFTER** initializing the broker: send messages, initialize objects, etc., you should use the `@app.after_startup` hook. diff --git a/docs/docs/en/getting_started/9_documentation.md b/docs/docs/en/getting_started/9_documentation.md index d1498552..f33d505d 100644 --- a/docs/docs/en/getting_started/9_documentation.md +++ b/docs/docs/en/getting_started/9_documentation.md @@ -7,6 +7,13 @@ hide: **Propan** allows you not to think about the documentation of your project - it is already generated automatically in accordance with the [**AsyncAPI**]({{ urls.asyncapi }}){.external-link target="_blank"} specification ! +!!! note "" + To work with a documentation you should install an extra requirements: + + ```console + pip install "propan[doc]" + ``` + ## Example Let's look at an example. diff --git a/docs/docs/en/index.md b/docs/docs/en/index.md index 7f234b37..c63e6249 100644 --- a/docs/docs/en/index.md +++ b/docs/docs/en/index.md @@ -51,6 +51,7 @@ It is a modern, high-level framework on top of popular Python libraries for vari * framework-independent way to manage the project environment * application code *hot reload* * robust application templates +* [**Documentation**](getting_started/9_documentation/): **Propan** automatically generates and presents an interactive [**AsyncAPI**]({{ urls.asyncapi }}){target="_blank"} documentation for your project * [**Testability**](getting_started/7_testing): **Propan** allows you to test your app without external dependencies: you do not have to set up a Message Broker, you can use a virtual one! --- diff --git a/docs/docs/ru/CHANGELOG.md b/docs/docs/ru/CHANGELOG.md index bcafa626..c1d48ff4 100644 --- a/docs/docs/ru/CHANGELOG.md +++ b/docs/docs/ru/CHANGELOG.md @@ -1,5 +1,29 @@ # CHANGELOG +## 2023-06-14 **0.1.3.0** AsyncAPI + +Π’Π΅ΠΊΡƒΡ‰Π΅Π΅ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ добавляСт Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π», Π½Π°Π΄ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ я усСрдно Ρ€Π°Π±ΠΎΡ‚Π°Π» послСдний мСсяц: +Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ **Propan** ΠΌΠΎΠΆΠ΅Ρ‚ автоматичСски Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈ Ρ…ΠΎΡΡ‚ΠΈΡ‚ΡŒ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡŽ для вашСго прилоТСния Π² +соотвСтствии со спСцификациСй [**AsyncAPI**](https://www.asyncapi.com/){.external-link target="_blank"}. + +Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ просто ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ смСТным ΠΊΠΎΠΌΠ°Π½Π΄Π°ΠΌ ссылку Π½Π° страницу с вашСй Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠ΅ΠΉ, Π³Π΄Π΅ ΠΎΠ½ΠΈ смогут ΠΎΠ·Π½Π°ΠΊΠΎΠΌΠΈΡ‚ΡŒΡΡ со всСми ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°ΠΌΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΎΠ³ΠΎ сСрвСра, ΠΊΠ°Π½Π°Π»ΠΎΠ² ΠΈ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΎΠΌ сообщСний, потрСбляСмых вашим сСрвисом. + +![HTML-page](../../assets/img/docs-html-short.png) + +ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅ с этим Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΠΎΠΌ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΠ·Π½Π°ΠΊΠΎΠΌΠΈΡ‚ΡŒΡΡ Π² ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΠ²ΡƒΡŽΡ‰Π΅ΠΌ [Ρ€Π°Π·Π΄Π΅Π»Π΅ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ](getting_started/9_documentation.md). + +Π’Π°ΠΊΠΆΠ΅, Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Π° Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ опрСдСлСния зависимостСй уровня Π±Ρ€ΠΎΠΊΠ΅Ρ€Π° ΠΈ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»Π΅ΠΉ: + +```python +from propan import RabbitBroker, Depends + +broker = RabbitBroker(dependencies=[Depends(...)]) + +@broker.handler(..., dependencies=[Depends(...)]) +async def handler(): + ... +``` + ## 2023-06-13 **0.1.2.17** Π’ этом ΠΎΠ±ΠΎΠ²Π»Π΅Π½ΠΈΠΈ стоит ΠΎΠ±ΠΎΠ±Ρ‰ΠΈΡ‚ΡŒ нСсколько измСнСния ΠΈ ΡƒΠ»ΡƒΡ‡ΡˆΠ΅Π½ΠΈΠΉ, Π²Ρ‹ΠΏΡƒΡ‰Π΅Π½Π½Ρ‹Ρ… с ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅Π³ΠΎ Ρ€Π΅Π»ΠΈΠ·Π°. diff --git a/docs/docs/ru/contributing/1_todo.md b/docs/docs/ru/contributing/1_todo.md index 60a8fd24..093e2761 100644 --- a/docs/docs/ru/contributing/1_todo.md +++ b/docs/docs/ru/contributing/1_todo.md @@ -16,16 +16,7 @@ ## Код -Если ΠΆΠ΅ Π²Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎΡ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с ΠΊΠΎΠ΄ΠΎΠΌ, Ρ‚ΠΎ Ρ‚ΡƒΡ‚ Ρƒ вас Π΅Ρ‰Π΅ большС возмоТностСй ΠΏΡ€ΠΎΡΠ²ΠΈΡ‚ΡŒ сСбя. На Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚ ΠΏΠ΅Ρ€Π΅Π΄ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΎΠΌ стоят ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ Π·Π°Π΄Π°Ρ‡ΠΈ: - -* `PushBackWatcher` Π΄ΠΎΠ»ΠΆΠ΅Π½ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ количСствС ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΎΠΊ сообщСния Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ΅: - это ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ‚ вСсти ΠΎΠ±Ρ‰ΠΈΠΉ счСтчик для всСх ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»Π΅ΠΉ. -* Π‘Π΄Π΅Π»Π°Ρ‚ΡŒ слияниС Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² `__init__` ΠΈ `connect` Π±Ρ€ΠΎΠΊΠ΅Ρ€ΠΎΠ² для Π±ΠΎΠ»Π΅Π΅ Π³ΠΈΠ±ΠΊΠΎΠ³ΠΎ управлСния Π΄Π΅Ρ„ΠΎΠ»Ρ‚Π½Ρ‹ΠΌΠΈ значСниями -* Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΡŽ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ прилоТСния Π² соотвСтствии с [Async API](https://www.asyncapi.com){target="_blank"} -* ΠŸΠΎΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ тСстами `NatsBroker` -* РСализация `NatsJSBroker` -* РСализация синхронной вСрсии прилоТСния ΠΈ Π±Ρ€ΠΎΠΊΠ΅Ρ€ΠΎΠ² -* РСализация Π±Ρ€ΠΎΠΊΠ΅Ρ€Π° для `Apache Kafka` ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΡ… Π±Ρ€ΠΎΠΊΠ΅Ρ€ΠΎΠ² ΠΈΠ· [ΠΏΠ»Π°Π½Π°](../../#_3) +ВсС Π°ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Π΅ Π·Π°Π΄Π°Ρ‡ΠΈ Π²Ρ‹ ΠΌΠΎΠ΅ΠΆΠ΅Ρ‚Π΅ Π½Π°ΠΉΡ‚ΠΈ Π² [Issues](https://github.com/Lancetnik/Propan/issues){.external-link target="_blank"}. Для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΈΡΡ‚ΡƒΠΏΠΈΡ‚ΡŒ ΠΊ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°, ΠΏΠ΅Ρ€Π΅ΠΉΠ΄ΠΈΡ‚Π΅ Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ [Ρ€Π°Π·Π΄Π΅Π»](../2_contributing-index/). diff --git a/docs/docs/ru/getting_started/1_quick-start.md b/docs/docs/ru/getting_started/1_quick-start.md index 2242aa4a..4ba93523 100644 --- a/docs/docs/ru/getting_started/1_quick-start.md +++ b/docs/docs/ru/getting_started/1_quick-start.md @@ -59,7 +59,17 @@ Propan ΠΈΠΌΠ΅Π΅Ρ‚ систСму управлСния зависимостями --- -## Π“ΠΎΡ‚ΠΎΠ²Ρ‹ΠΉ шаблон +## ДокумСнтация ΠŸΡ€ΠΎΠ΅ΠΊΡ‚Π° + +**Propan** автоматичСски Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡŽ для вашСго ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° Π² соотвСтсвии со спСцификациСй [**AsyncAPI**]({{ urls.asyncapi }}){target="_blank"}. Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ со сгСнСрированным Π°Ρ€Ρ‚Π΅Ρ„Π°ΠΊΡ‚Π°ΠΌΠΈ, Ρ‚Π°ΠΊ ΠΈ Ρ€Π°Π·ΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ Web-прСдставлСниС вашСй Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠ΅ Π½Π° рСсурсах, доступных для смСТных ΠΊΠΎΠΌΠ°Π½Π΄. + +НаличиС Ρ‚Π°ΠΊΠΎΠΉ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ сущСствСнно ΡƒΠΏΡ€ΠΎΡ‰Π°Π΅Ρ‚ ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΡŽ сСрвисов: Π²Ρ‹ сразу Π²ΠΈΠ΄ΠΈΡ‚Π΅, с ΠΊΠ°ΠΊΠΈΠΌΠΈ ΠΊΠ°Π½Π°Π»Π°ΠΌΠΈ ΠΈ ΠΊΠ°ΠΊΠΈΠΌ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΎΠΌ сообщСний Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅. А самоС Π³Π»Π°Π²Π½ΠΎΠ΅, это Π½Π΅ стоит Π²Π°ΠΌ Π½ΠΈΡ‡Π΅Π³ΠΎ - **Propan** ΡƒΠΆΠ΅ сдСлал всС Π·Π° вас! + +![HTML-page](../../assets/img/docs-html-short.png) + +--- + +## Π“ΠΎΡ‚ΠΎΠ²Ρ‹ΠΉ шаблон ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡΠ³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π³ΠΎΡ‚ΠΎΠ²Ρ‹ΠΉ ΠΊ использованию шаблон ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ **Propan CLI**: diff --git a/docs/docs/ru/getting_started/4_broker/3_type-casting.md b/docs/docs/ru/getting_started/4_broker/3_type-casting.md index 57ad8190..793387d6 100644 --- a/docs/docs/ru/getting_started/4_broker/3_type-casting.md +++ b/docs/docs/ru/getting_started/4_broker/3_type-casting.md @@ -2,13 +2,13 @@ ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΎΠ±Ρ€Π°ΠΌΠ»Π΅Π½Π½ΠΎΠΉ Π² `@broker.hanle` - это Ρ€Π°ΡΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ Ρ‚Π΅Π»ΠΎ входящСго сообщСния. -Оно ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Ρ‚Ρ€Π΅Ρ… Ρ‚ΠΈΠΏΠΎΠ²: +Π’Π΅Π»ΠΎ входящих сообщСний Π² **Propan** ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΎΠ΄Π½ΠΈΠΌ ΠΈΠ· Ρ‚Ρ€Π΅Ρ… Ρ‚ΠΈΠΏΠΎΠ²: * `str` - Ссли сообщСниС ΠΈΠΌΠ΅Π΅Ρ‚ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ `content-type: text/plain` * `dict` - Ссли сообщСниС ΠΈΠΌΠ΅Π΅Ρ‚ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ `content-type: application/json` * `bytes` - Ссли сообщСниС ΠΈΠΌΠ΅Π΅Ρ‚ любой Π΄Ρ€ΡƒΠ³ΠΎΠΉ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ -ВсС входящиС сообщСния Π±ΡƒΠ΄ΡƒΡ‚ автоматичСски приводится ΠΊ этому Π²ΠΈΠ΄Ρƒ. +Π’ качСствС Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ ΠΌΠΎΠ³ΡƒΡ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π»ΠΈΠ±ΠΎ эти Ρ‚ΠΈΠΏΡ‹, Π»ΠΈΠ±ΠΎ Π»ΡŽΠ±Ρ‹Π΅ ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²Π½Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹, ΠΊ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ **pydantic** смоТСт привСсти входящиС Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ `str -> float`). НСсколько ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠ²: @@ -65,3 +65,24 @@ async def base_handler(body: Message): БообщСния Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ Π²ΠΈΠ΄Π° ΡΠΏΡ€ΠΎΠ²ΠΎΡ†ΠΈΡ€ΡƒΡŽΡ‚ ΠΎΡˆΠΈΠ±ΠΊΡƒ ''' ``` + +### НСсколько Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² + +ΠŸΡ€ΠΈ Π°Π½Π½ΠΎΡ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… входящих Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ², Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Π±ΡƒΠ΄Π΅Ρ‚ равносилСн использованию использованию Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎΠΉ `pydantic` ΠΌΠΎΠ΄Π΅Π»ΠΈ. + +```python +from pydantic import BaseModel + +class Message(BaseModel): + a: int + b: float + +@broker.handle("test") +async def base_handler(a: int, b: float): +# async def base_handler(body: Message): - Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎ + ''' + ΠœΡ‹ ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌ application/json сообщСниС + Π’ΠΈΠ΄Π° { a: 1, b: 1.0 } + БообщСния Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ Π²ΠΈΠ΄Π° ΡΠΏΡ€ΠΎΠ²ΠΎΡ†ΠΈΡ€ΡƒΡŽΡ‚ ΠΎΡˆΠΈΠ±ΠΊΡƒ + ''' +``` diff --git a/docs/docs/ru/getting_started/5_dependency/1_di-index.md b/docs/docs/ru/getting_started/5_dependency/1_di-index.md index 16a54761..fa8b28df 100644 --- a/docs/docs/ru/getting_started/5_dependency/1_di-index.md +++ b/docs/docs/ru/getting_started/5_dependency/1_di-index.md @@ -48,7 +48,29 @@ nested: Π—Π΄Π΅ΡΡŒ вызываСтся влоТСнная зависимост !!! tip "АвтоматичСскоС ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠΉ @apply_types" Π’ ΠΊΠΎΠ΄Π΅ Π²Ρ‹ΡˆΠ΅ ΠΌΡ‹ Π½Π΅ использовали этот Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ для Π½Π°ΡˆΠΈΡ… зависимостСй. Однако, ΠΎΠ½ всС Ρ€Π°Π²Π½ΠΎ примСняСтся - ΠΊΠΎ всСм функциям, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹ΠΌ Π² качСствС зависимостСй. Π”Π΅Ρ€ΠΆΠΈΡ‚Π΅ это Π² ΡƒΠΌΠ΅. + ΠΊΠΎ всСм функциям, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹ΠΌ Π² качСствС зависимостСй. + +## Зависимости Π²Π΅Ρ€Ρ…Π½Π΅Π³ΠΎ уровня + +Если Π²Π°ΠΌ Π½Π΅ Π½ΡƒΠΆΠ΅Π½ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполнСния зависимостСй, Π²Ρ‹, ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ, ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΡƒΡŽ ΠΊΠΎΠ½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡŽ: + +```python +@broker.handle("test") +def method(_ = Depends(...)): ... +``` + +Однако, Π³ΠΎΡ€Π°Π·Π΄ΠΎ ΡƒΠ΄ΠΎΠ±Π½Π΅Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ для этого ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° `handle` + +```python +@broker.handle("test", dependencies=[Depends(...)]) +def method(): ... +``` + +Π’Π°ΠΊΠΆΠ΅ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΠ±ΡŠΡΠ²ΠΈΡ‚ΡŒ Ρ‚Π°ΠΊΠΈΠ΅ зависимости Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ Π±Ρ€ΠΎΠΊΠ΅Ρ€Π°: Π² Ρ‚Π°ΠΊΠΎΠΌ случаС, ΠΎΠ½ΠΈ Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡ‚ΡŒΡΡ ΠΊΠΎ всСм ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°ΠΌ этого Π±Ρ€ΠΎΠΊΠ΅Ρ€Π°. + +```python +broker = RabbitBroker(dependencies=[Depends(...)]) +``` ## Π’Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Π΅ зависимости @@ -88,8 +110,7 @@ nested: Π—Π΄Π΅ΡΡŒ вызываСтся влоТСнная зависимост ## ΠŸΡ€ΠΈΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Ρ‚ΠΈΠΏΠΎΠ² зависимостСй **FastDepends**, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹ΠΉ **Propan**, Ρ‚Π°ΠΊΠΆΠ΅ ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ Ρ‚ΠΈΠΏ `return`. Π­Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ΅ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΡŒΡŽ Π±ΡƒΠ΄Π΅Ρ‚ -Π΄Π²Π°ΠΆΠ΄Ρ‹ ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ΡŒΡΡ ΠΊ Ρ‚ΠΈΠΏΡƒ: ΠΊΠ°ΠΊ `return` это зависимости ΠΈ ΠΊΠ°ΠΊ Π²Ρ…ΠΎΠ΄Π½ΠΎΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ основной Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ. Π­Ρ‚ΠΎ Π½Π΅ нСсСт Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… расходов, Ссли -эти Ρ‚ΠΈΠΏΡ‹ ΠΈΠΌΠ΅ΡŽΡ‚ ΠΎΠ΄Π½Ρƒ ΠΈ Ρ‚Ρƒ ΠΆΠ΅ Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΡŽ. ΠŸΡ€ΠΎΡΡ‚ΠΎ Π΄Π΅Ρ€ΠΆΠΈΡ‚Π΅ это Π² Π³ΠΎΠ»ΠΎΠ²Π΅. Или Π½Π΅Ρ‚... Π’ любом случаС, я вас ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅Π΄ΠΈΠ». +Π΄Π²Π°ΠΆΠ΄Ρ‹ ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ΡŒΡΡ ΠΊ Ρ‚ΠΈΠΏΡƒ: ΠΊΠ°ΠΊ `return` этой зависимости ΠΈ ΠΊΠ°ΠΊ Π²Ρ…ΠΎΠ΄Π½ΠΎΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ основной Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ. Π­Ρ‚ΠΎ Π½Π΅ нСсСт Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… расходов, Ссли эти Ρ‚ΠΈΠΏΡ‹ ΠΈΠΌΠ΅ΡŽΡ‚ ΠΎΠ΄Π½Ρƒ ΠΈ Ρ‚Ρƒ ΠΆΠ΅ Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΡŽ. ΠŸΡ€ΠΎΡΡ‚ΠΎ Π΄Π΅Ρ€ΠΆΠΈΡ‚Π΅ это Π² Π³ΠΎΠ»ΠΎΠ²Π΅. Или Π½Π΅Ρ‚... Π’ любом случаС, я вас ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅Π΄ΠΈΠ». ```python linenums="1" from propan import Depends, apply_types @@ -108,4 +129,4 @@ assert method("1") == 5 Π’Π°ΠΊΠΆΠ΅, Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполнСния зависимости ΠΊΠ΅ΡˆΠΈΡ€ΡƒΠ΅Ρ‚ΡΡ. Если Π²Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ эту зависимости Π² `N` функциях, этот Π·Π°ΠΊΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Π±ΡƒΠ΄Π΅Ρ‚ приводится ΠΊ Ρ‚ΠΈΠΏΡƒ `N` Ρ€Π°Π· (Π½Π° Π²Ρ…ΠΎΠ΄Π΅ Π² ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ). -Для избСТания ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ с этим, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ [mypy](https://www.mypy-lang.org){target="_blank"} ΠΈΠ»ΠΈ просто Π±ΡƒΠ΄ΡŒΡ‚Π΅ Π°ΠΊΠΊΡƒΡ€Π°Ρ‚Π½Ρ‹ с Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠ΅ΠΉ Ρ‚ΠΈΠΏΠΎΠ² Π² вашСм ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅. +Π§Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ ΠΏΠΎΡ‚Π΅Π½Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹Ρ… ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ [mypy](https://www.mypy-lang.org){target="_blank"} ΠΈΠ»ΠΈ просто Π±ΡƒΠ΄ΡŒΡ‚Π΅ Π°ΠΊΠΊΡƒΡ€Π°Ρ‚Π½Ρ‹ с Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠ΅ΠΉ Ρ‚ΠΈΠΏΠΎΠ² Π² вашСм ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅. diff --git a/docs/docs/ru/getting_started/6_lifespans.md b/docs/docs/ru/getting_started/6_lifespans.md index 8f4e0125..4a313023 100644 --- a/docs/docs/ru/getting_started/6_lifespans.md +++ b/docs/docs/ru/getting_started/6_lifespans.md @@ -113,3 +113,5 @@ propan run serve:app --env .env.test ### Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ Π±Ρ€ΠΎΠΊΠ΅Ρ€Π° Π₯ΡƒΠΊΠΈ `@app.on_startup` Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ **Π”Πž** запуска Π±Ρ€ΠΎΠΊΠ΅Ρ€Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΠΌ. Π₯ΡƒΠΊΠΈ `@app.after_shutdown` Π·Π°ΠΏΡƒΡΠΊΠ°ΡŽΡ‚ΡΡ **ΠŸΠžΠ‘Π›Π•** остановки Π±Ρ€ΠΎΠΊΠ΅Ρ€Π°. + +Если ΠΆΠ΅ Π²Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΡΠΎΠ²Π΅Ρ€ΡˆΠΈΡ‚ΡŒ ΠΊΠ°ΠΊΠΈΠ΅-Ρ‚ΠΎ дСйствия **ΠŸΠžΠ‘Π›Π•** ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π±Ρ€ΠΎΠΊΠ΅Ρ€Π°: ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ сообщСния, ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ ΠΈ Ρ‚.Π΄., Π²Π°ΠΌ стоит ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ…ΡƒΠΊ `@app.after_startup`. diff --git a/docs/docs/ru/getting_started/9_documentation.md b/docs/docs/ru/getting_started/9_documentation.md index 964f03c3..8f1d37f9 100644 --- a/docs/docs/ru/getting_started/9_documentation.md +++ b/docs/docs/ru/getting_started/9_documentation.md @@ -7,6 +7,13 @@ hide: **Propan** позволяСт Π²Π°ΠΌ Π½Π΅ Π΄ΡƒΠΌΠ°Ρ‚ΡŒ ΠΎ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ своСго ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° - ΠΎΠ½Π° ΡƒΠΆΠ΅ сгСнСрирована автоматичСски Π² соотвСтсвии со спСцификациСй [**AsyncAPI**]({{ urls.asyncapi }}){.external-link target="_blank"}! +!!! note "" + Для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠ΅ΠΉ Π²Π°ΠΌ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ зависимости: + + ```console + pip install "propan[doc]" + ``` + ## ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Π”Π°Π²Π°ΠΉΡ‚Π΅ разбСрСмся Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅, ΠΊΠ°ΠΊ это Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚. diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 845f7851..176982b3 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -54,6 +54,7 @@ theme: plugins: - search + - glightbox - macros: include_dir: includes - i18n: diff --git a/examples/grpc/gen_py_code.sh b/examples/grpc/gen_py_code.sh new file mode 100644 index 00000000..ab5b2fc8 --- /dev/null +++ b/examples/grpc/gen_py_code.sh @@ -0,0 +1 @@ +python -m grpc_tools.protoc --python_out=. --pyi_out=. -I . message.proto \ No newline at end of file diff --git a/examples/grpc/grpc_encoding.py b/examples/grpc/grpc_encoding.py new file mode 100644 index 00000000..1542319a --- /dev/null +++ b/examples/grpc/grpc_encoding.py @@ -0,0 +1,25 @@ +from message_pb2 import Person + +from propan import PropanApp, RabbitBroker +from propan.annotations import Logger, NoCast +from propan.brokers.rabbit import RabbitMessage + +broker = RabbitBroker() +app = PropanApp(broker) + + +async def decode_message(msg: RabbitMessage, *args) -> Person: + decoded = Person() + decoded.ParseFromString(msg.body) + return decoded + + +@broker.handle("test", decode_message=decode_message) +async def consume(body: NoCast[Person], logger: Logger): + logger.info(body) + + +@app.after_startup +async def publish(): + body = Person(name="john", age=25).SerializeToString() + await broker.publish(body, "test") diff --git a/examples/grpc/message.proto b/examples/grpc/message.proto new file mode 100644 index 00000000..91552f70 --- /dev/null +++ b/examples/grpc/message.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message Person { + string name = 1; + float age = 2; +} \ No newline at end of file diff --git a/examples/grpc/requirements.txt b/examples/grpc/requirements.txt new file mode 100644 index 00000000..4a2666eb --- /dev/null +++ b/examples/grpc/requirements.txt @@ -0,0 +1 @@ +grpcio-tools \ No newline at end of file diff --git a/propan/__about__.py b/propan/__about__.py index 35b4f3b4..99fbe0ff 100644 --- a/propan/__about__.py +++ b/propan/__about__.py @@ -2,7 +2,7 @@ from unittest.mock import Mock -__version__ = "0.1.2.17" +__version__ = "0.1.3.0" INSTALL_MESSAGE = ( diff --git a/propan/annotations.py b/propan/annotations.py index 50533ddd..198c4ea4 100644 --- a/propan/annotations.py +++ b/propan/annotations.py @@ -1,16 +1,19 @@ import logging -from typing_extensions import Annotated +from typing_extensions import Annotated, TypeVar from propan import __about__ as about from propan.cli.app import PropanApp from propan.utils.context import Context as ContextField from propan.utils.context import ContextRepo as CR +from propan.utils.no_cast import NoCast as NC Logger = Annotated[logging.Logger, ContextField("logger")] App = Annotated[PropanApp, ContextField("app")] ContextRepo = Annotated[CR, ContextField("context")] +NoCastType = TypeVar("NoCastType") +NoCast = Annotated[NoCastType, NC()] try: import aio_pika diff --git a/propan/brokers/kafka/__init__.py b/propan/brokers/kafka/__init__.py index 03601b41..3b727957 100644 --- a/propan/brokers/kafka/__init__.py +++ b/propan/brokers/kafka/__init__.py @@ -1,3 +1,3 @@ -from propan.brokers.kafka.kafka_broker import KafkaBroker +from propan.brokers.kafka.kafka_broker import KafkaBroker, KafkaMessage -__all__ = ("KafkaBroker",) +__all__ = ("KafkaBroker", "KafkaMessage") diff --git a/propan/brokers/kafka/kafka_broker.pyi b/propan/brokers/kafka/kafka_broker.pyi index e336f45b..0d8c37ce 100644 --- a/propan/brokers/kafka/kafka_broker.pyi +++ b/propan/brokers/kafka/kafka_broker.pyi @@ -33,7 +33,7 @@ from propan.brokers._model.schemas import PropanMessage from propan.brokers.kafka.schemas import Handler from propan.brokers.push_back_watcher import BaseWatcher from propan.log import access_logger -from propan.types import DecodedMessage, SendableMessage, HandlerWrapper +from propan.types import DecodedMessage, HandlerWrapper, SendableMessage T = TypeVar("T") Partition = TypeVar("Partition") diff --git a/propan/brokers/nats/__init__.py b/propan/brokers/nats/__init__.py index ce45a20f..c07c8a7b 100644 --- a/propan/brokers/nats/__init__.py +++ b/propan/brokers/nats/__init__.py @@ -1,3 +1,3 @@ -from propan.brokers.nats.nats_broker import NatsBroker +from propan.brokers.nats.nats_broker import NatsBroker, NatsMessage -__all__ = ("NatsBroker",) +__all__ = ("NatsBroker", "NatsMessage") diff --git a/propan/brokers/rabbit/__init__.py b/propan/brokers/rabbit/__init__.py index e6219987..aaa2a391 100644 --- a/propan/brokers/rabbit/__init__.py +++ b/propan/brokers/rabbit/__init__.py @@ -1,4 +1,4 @@ -from propan.brokers.rabbit.rabbit_broker import RabbitBroker +from propan.brokers.rabbit.rabbit_broker import RabbitBroker, RabbitMessage from propan.brokers.rabbit.schemas import ExchangeType, RabbitExchange, RabbitQueue __all__ = ( @@ -6,4 +6,5 @@ "RabbitQueue", "RabbitExchange", "ExchangeType", + "RabbitMessage", ) diff --git a/propan/brokers/rabbit/rabbit_broker.py b/propan/brokers/rabbit/rabbit_broker.py index b4eeb1a6..7146e81c 100644 --- a/propan/brokers/rabbit/rabbit_broker.py +++ b/propan/brokers/rabbit/rabbit_broker.py @@ -377,7 +377,7 @@ async def _init_queue( ) -> aio_pika.abc.AbstractRobustQueue: warnings.warn( "The `_init_queue` method is deprecated, " # noqa: E501 - "and will be removed in version 1.3.0. " # noqa: E501 + "and will be removed in version 1.4.0. " # noqa: E501 "Use `declare_queue` instead.", # noqa: E501 category=DeprecationWarning, stacklevel=1, @@ -394,7 +394,7 @@ async def _init_exchange( ) -> aio_pika.abc.AbstractRobustExchange: warnings.warn( "The `_init_exchange` method is deprecated, " # noqa: E501 - "and will be removed in version 1.3.0. " # noqa: E501 + "and will be removed in version 1.4.0. " # noqa: E501 "Use `declare_exchange` instead.", # noqa: E501 category=DeprecationWarning, stacklevel=1, diff --git a/propan/brokers/rabbit/rabbit_broker.pyi b/propan/brokers/rabbit/rabbit_broker.pyi index 06807aea..ea20dfe5 100644 --- a/propan/brokers/rabbit/rabbit_broker.pyi +++ b/propan/brokers/rabbit/rabbit_broker.pyi @@ -4,7 +4,6 @@ from typing import ( Any, Awaitable, Callable, - Coroutine, Dict, List, Optional, diff --git a/propan/brokers/rabbit/schemas.py b/propan/brokers/rabbit/schemas.py index 3ff62ca5..9d2ce948 100644 --- a/propan/brokers/rabbit/schemas.py +++ b/propan/brokers/rabbit/schemas.py @@ -36,12 +36,13 @@ class RabbitQueue(Queue): routing_key: str = Field(default="", exclude=True) def __hash__(self) -> int: - return ( - hash(self.name) - + int(self.durable) - + int(self.passive) - + int(self.exclusive) - + int(self.auto_delete) + return sum( + ( + hash(self.name), + int(self.durable), + int(self.exclusive), + int(self.auto_delete), + ) ) @property @@ -90,12 +91,13 @@ class RabbitExchange(NameRequired): routing_key: str = Field(default="", exclude=True) def __hash__(self) -> int: - return ( - hash(self.name) - + hash(self.type.value) - + int(self.durable) - + int(self.passive) - + int(self.auto_delete) + return sum( + ( + hash(self.name), + hash(self.type.value), + int(self.durable), + int(self.auto_delete), + ) ) def __init__( diff --git a/propan/brokers/redis/__init__.py b/propan/brokers/redis/__init__.py index 519811df..afc01254 100644 --- a/propan/brokers/redis/__init__.py +++ b/propan/brokers/redis/__init__.py @@ -1,3 +1,3 @@ -from propan.brokers.redis.redis_broker import RedisBroker +from propan.brokers.redis.redis_broker import RedisBroker, RedisMessage -__all__ = ("RedisBroker",) +__all__ = ("RedisBroker", "RedisMessage") diff --git a/propan/brokers/redis/redis_broker.py b/propan/brokers/redis/redis_broker.py index d90f5633..4ea4c005 100644 --- a/propan/brokers/redis/redis_broker.py +++ b/propan/brokers/redis/redis_broker.py @@ -214,7 +214,7 @@ async def publish( task.cancel() @staticmethod - async def _parse_message(message: Any) -> RedisMessage: + async def _parse_message(message: AnyCallable) -> RedisMessage: data = message.get("data", b"") try: diff --git a/propan/brokers/sqs/__init__.py b/propan/brokers/sqs/__init__.py index f1b256c4..98e74af7 100644 --- a/propan/brokers/sqs/__init__.py +++ b/propan/brokers/sqs/__init__.py @@ -2,10 +2,9 @@ FifoQueue, RedriveAllowPolicy, RedrivePolicy, - SQSMessage, SQSQueue, ) -from propan.brokers.sqs.sqs_broker import SQSBroker +from propan.brokers.sqs.sqs_broker import SQSBroker, SQSMessage __all__ = ( "SQSBroker", diff --git a/propan/test/sqs.py b/propan/test/sqs.py index 893a62f5..b17cb19f 100644 --- a/propan/test/sqs.py +++ b/propan/test/sqs.py @@ -11,7 +11,7 @@ from unittest.mock import AsyncMock from propan import SQSBroker -from propan.brokers.sqs import SQSMessage +from propan.brokers.sqs.schema import SQSMessage from propan.test.utils import call_handler from propan.types import SendableMessage diff --git a/propan/utils/__init__.py b/propan/utils/__init__.py index b2889b7c..cb43ae93 100644 --- a/propan/utils/__init__.py +++ b/propan/utils/__init__.py @@ -1,7 +1,8 @@ from fast_depends import Depends from fast_depends import inject as apply_types -from .context import Context, ContextRepo, context +from propan.utils.context import Context, ContextRepo, context +from propan.utils.no_cast import NoCast __all__ = ( "apply_types", @@ -9,4 +10,5 @@ "Context", "ContextRepo", "Depends", + "NoCast", ) diff --git a/propan/utils/no_cast.py b/propan/utils/no_cast.py new file mode 100644 index 00000000..158fa25b --- /dev/null +++ b/propan/utils/no_cast.py @@ -0,0 +1,11 @@ +from fast_depends.library import CustomField + +from propan.types import AnyDict + + +class NoCast(CustomField): # type: ignore + def __init__(self) -> None: + super().__init__(cast=False) + + def use(self, **kwargs: AnyDict) -> AnyDict: + return kwargs diff --git a/pyproject.toml b/pyproject.toml index bfe4e4e5..b18ab5e3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -113,6 +113,7 @@ dev-doc = [ "mkdocs-static-i18n", "mdx-include >=1.4.1,<2.0.0", "mkdocs-macros-plugin", + "mkdocs-glightbox", "typer[all]", ] From 0648559aadd555ba2f08e70c11f8580865fda953 Mon Sep 17 00:00:00 2001 From: Lancetnik Date: Wed, 14 Jun 2023 20:58:35 +0300 Subject: [PATCH 18/18] check separated dependencies --- propan/asyncapi/info.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/propan/asyncapi/info.py b/propan/asyncapi/info.py index 715810dc..22a05807 100644 --- a/propan/asyncapi/info.py +++ b/propan/asyncapi/info.py @@ -1,6 +1,12 @@ +import importlib.util from typing import Optional -from pydantic import BaseModel, EmailStr, Field, HttpUrl +from pydantic import BaseModel, Field, HttpUrl + +if importlib.util.find_spec("email_validator"): + from pydantic import EmailStr +else: + EmailStr = str class AsyncAPIContact(BaseModel):

IeN#glJ=JD*P3JC|xq$Wr3PHa0q- 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 literal 0 HcmV?d00001 diff --git a/docs/docs/assets/img/docs-html.png b/docs/docs/assets/img/docs-html.png new file mode 100644 index 0000000000000000000000000000000000000000..b505e660081dbc86ff970eb3d75f9654674f4ec5 GIT binary patch literal 382283 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 z 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