jararaca 0.2.37a12__py3-none-any.whl → 0.4.0a5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- README.md +121 -0
- jararaca/__init__.py +267 -15
- jararaca/__main__.py +4 -0
- jararaca/broker_backend/__init__.py +106 -0
- jararaca/broker_backend/mapper.py +25 -0
- jararaca/broker_backend/redis_broker_backend.py +168 -0
- jararaca/cli.py +840 -103
- jararaca/common/__init__.py +3 -0
- jararaca/core/__init__.py +3 -0
- jararaca/core/providers.py +4 -0
- jararaca/core/uow.py +55 -16
- jararaca/di.py +4 -0
- jararaca/files/entity.py.mako +4 -0
- jararaca/lifecycle.py +6 -2
- jararaca/messagebus/__init__.py +5 -1
- jararaca/messagebus/bus_message_controller.py +4 -0
- jararaca/messagebus/consumers/__init__.py +3 -0
- jararaca/messagebus/decorators.py +90 -85
- jararaca/messagebus/implicit_headers.py +49 -0
- jararaca/messagebus/interceptors/__init__.py +3 -0
- jararaca/messagebus/interceptors/aiopika_publisher_interceptor.py +95 -37
- jararaca/messagebus/interceptors/publisher_interceptor.py +42 -0
- jararaca/messagebus/message.py +31 -0
- jararaca/messagebus/publisher.py +47 -4
- jararaca/messagebus/worker.py +1615 -135
- jararaca/microservice.py +248 -36
- jararaca/observability/constants.py +7 -0
- jararaca/observability/decorators.py +177 -16
- jararaca/observability/fastapi_exception_handler.py +37 -0
- jararaca/observability/hooks.py +109 -0
- jararaca/observability/interceptor.py +8 -2
- jararaca/observability/providers/__init__.py +3 -0
- jararaca/observability/providers/otel.py +213 -18
- jararaca/persistence/base.py +40 -3
- jararaca/persistence/exports.py +4 -0
- jararaca/persistence/interceptors/__init__.py +3 -0
- jararaca/persistence/interceptors/aiosqa_interceptor.py +187 -23
- jararaca/persistence/interceptors/constants.py +5 -0
- jararaca/persistence/interceptors/decorators.py +50 -0
- jararaca/persistence/session.py +3 -0
- jararaca/persistence/sort_filter.py +4 -0
- jararaca/persistence/utilities.py +74 -32
- jararaca/presentation/__init__.py +3 -0
- jararaca/presentation/decorators.py +170 -82
- jararaca/presentation/exceptions.py +23 -0
- jararaca/presentation/hooks.py +4 -0
- jararaca/presentation/http_microservice.py +4 -0
- jararaca/presentation/server.py +120 -41
- jararaca/presentation/websocket/__init__.py +3 -0
- jararaca/presentation/websocket/base_types.py +4 -0
- jararaca/presentation/websocket/context.py +34 -4
- jararaca/presentation/websocket/decorators.py +8 -41
- jararaca/presentation/websocket/redis.py +280 -53
- jararaca/presentation/websocket/types.py +6 -2
- jararaca/presentation/websocket/websocket_interceptor.py +74 -23
- jararaca/reflect/__init__.py +3 -0
- jararaca/reflect/controller_inspect.py +81 -0
- jararaca/reflect/decorators.py +238 -0
- jararaca/reflect/metadata.py +76 -0
- jararaca/rpc/__init__.py +3 -0
- jararaca/rpc/http/__init__.py +101 -0
- jararaca/rpc/http/backends/__init__.py +14 -0
- jararaca/rpc/http/backends/httpx.py +43 -9
- jararaca/rpc/http/backends/otel.py +4 -0
- jararaca/rpc/http/decorators.py +378 -113
- jararaca/rpc/http/httpx.py +3 -0
- jararaca/scheduler/__init__.py +3 -0
- jararaca/scheduler/beat_worker.py +758 -0
- jararaca/scheduler/decorators.py +89 -28
- jararaca/scheduler/types.py +11 -0
- jararaca/tools/app_config/__init__.py +3 -0
- jararaca/tools/app_config/decorators.py +7 -19
- jararaca/tools/app_config/interceptor.py +10 -4
- jararaca/tools/typescript/__init__.py +3 -0
- jararaca/tools/typescript/decorators.py +120 -0
- jararaca/tools/typescript/interface_parser.py +1126 -189
- jararaca/utils/__init__.py +3 -0
- jararaca/utils/rabbitmq_utils.py +372 -0
- jararaca/utils/retry.py +148 -0
- jararaca-0.4.0a5.dist-info/LICENSE +674 -0
- jararaca-0.4.0a5.dist-info/LICENSES/GPL-3.0-or-later.txt +232 -0
- {jararaca-0.2.37a12.dist-info → jararaca-0.4.0a5.dist-info}/METADATA +14 -7
- jararaca-0.4.0a5.dist-info/RECORD +88 -0
- {jararaca-0.2.37a12.dist-info → jararaca-0.4.0a5.dist-info}/WHEEL +1 -1
- pyproject.toml +131 -0
- jararaca/messagebus/types.py +0 -30
- jararaca/scheduler/scheduler.py +0 -154
- jararaca/tools/metadata.py +0 -47
- jararaca-0.2.37a12.dist-info/RECORD +0 -63
- /jararaca-0.2.37a12.dist-info/LICENSE → /LICENSE +0 -0
- {jararaca-0.2.37a12.dist-info → jararaca-0.4.0a5.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2025 Lucas S
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
4
|
+
|
|
5
|
+
from contextlib import asynccontextmanager
|
|
6
|
+
from typing import AsyncContextManager, AsyncGenerator, Protocol
|
|
7
|
+
|
|
8
|
+
from jararaca.broker_backend import MessageBrokerBackend
|
|
9
|
+
from jararaca.messagebus.publisher import MessagePublisher, provide_message_publisher
|
|
10
|
+
from jararaca.microservice import AppInterceptor, AppTransactionContext
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class MessageBusConnectionFactory(Protocol):
|
|
14
|
+
|
|
15
|
+
def provide_connection(self) -> AsyncContextManager[MessagePublisher]: ...
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class MessageBusPublisherInterceptor(AppInterceptor):
|
|
19
|
+
|
|
20
|
+
def __init__(
|
|
21
|
+
self,
|
|
22
|
+
connection_factory: MessageBusConnectionFactory,
|
|
23
|
+
connection_name: str = "default",
|
|
24
|
+
message_scheduler: MessageBrokerBackend | None = None,
|
|
25
|
+
):
|
|
26
|
+
self.connection_factory = connection_factory
|
|
27
|
+
self.connection_name = connection_name
|
|
28
|
+
self.message_scheduler = message_scheduler
|
|
29
|
+
|
|
30
|
+
@asynccontextmanager
|
|
31
|
+
async def intercept(
|
|
32
|
+
self, app_context: AppTransactionContext
|
|
33
|
+
) -> AsyncGenerator[None, None]:
|
|
34
|
+
if app_context.transaction_data.context_type == "websocket":
|
|
35
|
+
yield
|
|
36
|
+
return
|
|
37
|
+
|
|
38
|
+
async with self.connection_factory.provide_connection() as connection:
|
|
39
|
+
with provide_message_publisher(self.connection_name, connection):
|
|
40
|
+
yield
|
|
41
|
+
|
|
42
|
+
await connection.flush()
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2025 Lucas S
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
4
|
+
|
|
5
|
+
from datetime import datetime, tzinfo
|
|
6
|
+
from typing import Generic, Protocol, TypeVar
|
|
7
|
+
|
|
8
|
+
from jararaca.messagebus.publisher import IMessage, use_publisher
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Message(IMessage):
|
|
12
|
+
|
|
13
|
+
async def publish(self) -> None:
|
|
14
|
+
task_publisher = use_publisher()
|
|
15
|
+
await task_publisher.publish(self, self.MESSAGE_TOPIC)
|
|
16
|
+
|
|
17
|
+
async def delay(self, seconds: int) -> None:
|
|
18
|
+
task_publisher = use_publisher()
|
|
19
|
+
await task_publisher.delay(self, seconds)
|
|
20
|
+
|
|
21
|
+
async def schedule(self, when: datetime, tz: tzinfo) -> None:
|
|
22
|
+
task_publisher = use_publisher()
|
|
23
|
+
await task_publisher.schedule(self, when, tz)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
INHERITS_MESSAGE_CO = TypeVar("INHERITS_MESSAGE_CO", bound=Message, covariant=True)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class MessageOf(Protocol, Generic[INHERITS_MESSAGE_CO]):
|
|
30
|
+
|
|
31
|
+
def payload(self) -> INHERITS_MESSAGE_CO: ...
|
jararaca/messagebus/publisher.py
CHANGED
|
@@ -1,13 +1,56 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2025 Lucas S
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
4
|
+
|
|
5
|
+
from abc import ABC, abstractmethod
|
|
1
6
|
from contextlib import contextmanager, suppress
|
|
2
7
|
from contextvars import ContextVar
|
|
3
|
-
from
|
|
8
|
+
from datetime import datetime, tzinfo
|
|
9
|
+
from typing import Any, ClassVar, Generator, Literal
|
|
4
10
|
|
|
5
11
|
from pydantic import BaseModel
|
|
6
12
|
|
|
7
13
|
|
|
8
|
-
class
|
|
9
|
-
|
|
10
|
-
|
|
14
|
+
class IMessage(BaseModel):
|
|
15
|
+
"""
|
|
16
|
+
Base class for messages representing tasks.
|
|
17
|
+
A Task is a message that represents a unit of work to be done.
|
|
18
|
+
It is published to a TaskPublisher and consumed by a TaskHandler, wrapped in TaskData.
|
|
19
|
+
Note: A Task is not an Event.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
MESSAGE_TOPIC: ClassVar[str] = "__unset__"
|
|
23
|
+
|
|
24
|
+
MESSAGE_TYPE: ClassVar[Literal["task", "event"]] = "task"
|
|
25
|
+
|
|
26
|
+
MESSAGE_CATEGORY: ClassVar[str] = "uncategorized"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class MessagePublisher(ABC):
|
|
30
|
+
@abstractmethod
|
|
31
|
+
async def publish(self, message: IMessage, topic: str) -> None:
|
|
32
|
+
pass
|
|
33
|
+
|
|
34
|
+
@abstractmethod
|
|
35
|
+
async def delay(self, message: IMessage, seconds: int) -> None:
|
|
36
|
+
"""
|
|
37
|
+
Delay the message for a given number of seconds.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
@abstractmethod
|
|
41
|
+
async def schedule(
|
|
42
|
+
self, message: IMessage, when: datetime, timezone: tzinfo
|
|
43
|
+
) -> None:
|
|
44
|
+
"""
|
|
45
|
+
Schedule the message for a given datetime.
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
@abstractmethod
|
|
49
|
+
async def flush(self) -> None:
|
|
50
|
+
"""
|
|
51
|
+
Publish all messages that have been delayed or scheduled.
|
|
52
|
+
This is typically called at the end of a request or task processing.
|
|
53
|
+
"""
|
|
11
54
|
|
|
12
55
|
|
|
13
56
|
message_publishers_ctx = ContextVar[dict[str, MessagePublisher]](
|