python-cq 0.23.1__py3-none-any.whl → 0.24.0__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.
cq/__init__.py CHANGED
@@ -12,9 +12,7 @@ from ._core.queuing.pump import Pump
12
12
  from ._core.queuing.queues.abc import Consumer, Delivery, Producer, Queue
13
13
  from ._core.queuing.queues.memory import MemoryQueue
14
14
  from ._core.related_events import AnyIORelatedEvents, RelatedEvents
15
- from ._core.routing.command_pipeline import (
16
- ContextCommandPipeline as _ContextCommandPipeline,
17
- )
15
+ from ._core.routing.command_pipeline import ContextCommandPipeline
18
16
  from ._core.routing.di import DIAdapter
19
17
  from ._core.routing.dispatchers.abc import Dispatcher
20
18
  from ._core.routing.dispatchers.bus import Bus
@@ -77,9 +75,4 @@ new_command_bus = __router__.new_command_bus
77
75
  new_event_bus = __router__.new_event_bus
78
76
  new_query_bus = __router__.new_query_bus
79
77
 
80
-
81
- class ContextCommandPipeline[C: Command](_ContextCommandPipeline[C]):
82
- __slots__ = ()
83
-
84
- def __init__(self, di: DIAdapter = __router__.di) -> None:
85
- super().__init__(di)
78
+ ContextCommandPipeline._set_default_di(__router__.di)
@@ -1,4 +1,4 @@
1
- from typing import TYPE_CHECKING, Any, Self, overload
1
+ from typing import TYPE_CHECKING, Any, ClassVar, Self, overload
2
2
 
3
3
  from cq._core.common.typing import Decorator
4
4
  from cq._core.message import Command, CommandBus, Query, QueryBus
@@ -18,7 +18,10 @@ class ContextCommandPipeline[C: Command](ContextPipeline[C]):
18
18
 
19
19
  __query_dispatcher: Dispatcher[Query, Any]
20
20
 
21
- def __init__(self, di: DIAdapter) -> None:
21
+ __default_di: ClassVar[DIAdapter]
22
+
23
+ def __init__(self, di: DIAdapter | None = None, /) -> None:
24
+ di = di or self.__default_di
22
25
  super().__init__(LazyDispatcher(CommandBus, di))
23
26
  self.__query_dispatcher = LazyDispatcher(QueryBus, di)
24
27
 
@@ -50,3 +53,7 @@ class ContextCommandPipeline[C: Command](ContextPipeline[C]):
50
53
  /,
51
54
  ) -> Any:
52
55
  return self.step(wrapped, dispatcher=self.__query_dispatcher)
56
+
57
+ @classmethod
58
+ def _set_default_di(cls, di: DIAdapter, /) -> None:
59
+ cls.__default_di = di
cq/_core/routing/di.py CHANGED
@@ -2,11 +2,8 @@ from __future__ import annotations
2
2
 
3
3
  from abc import abstractmethod
4
4
  from collections.abc import Awaitable, Callable
5
- from contextlib import nullcontext
6
5
  from typing import TYPE_CHECKING, Any, Concatenate, Protocol, runtime_checkable
7
6
 
8
- from cq.middlewares.contextlib import AsyncContextManagerMiddleware
9
-
10
7
  if TYPE_CHECKING: # pragma: no cover
11
8
  from cq import Command, CommandBus, EventBus, Middleware, QueryBus
12
9
 
@@ -23,8 +20,7 @@ class DIAdapter(Protocol):
23
20
 
24
21
  __slots__ = ()
25
22
 
26
- @abstractmethod
27
- def command_scope(self) -> Middleware[Concatenate[Command, ...], Any]:
23
+ def command_scope(self) -> Middleware[Concatenate[Command, ...], Any] | None:
28
24
  """
29
25
  Return a middleware that wraps each command dispatch.
30
26
 
@@ -39,7 +35,7 @@ class DIAdapter(Protocol):
39
35
  instead of writing the middleware by hand.
40
36
  """
41
37
 
42
- raise NotImplementedError
38
+ return None
43
39
 
44
40
  @abstractmethod
45
41
  def lazy[T](self, tp: type[T]) -> Callable[[], Awaitable[T]]:
@@ -88,9 +84,6 @@ class DIAdapter(Protocol):
88
84
  class NoDI(DIAdapter):
89
85
  __slots__ = ()
90
86
 
91
- def command_scope(self) -> Middleware[Concatenate[Command, ...], Any]:
92
- return AsyncContextManagerMiddleware(nullcontext())
93
-
94
87
  def lazy[T](self, tp: type[T], /) -> Callable[[], Awaitable[T]]:
95
88
  tp_str = getattr(tp, "__name__", str(tp))
96
89
  raise RuntimeError(
@@ -2,6 +2,7 @@ from collections.abc import KeysView
2
2
  from typing import Any, Self
3
3
 
4
4
  from cq._core.message import Command, Event, Query
5
+ from cq._core.routing.command_pipeline import ContextCommandPipeline
5
6
  from cq._core.routing.di import DIAdapter, NoDI
6
7
  from cq._core.routing.dispatchers.bus import Bus, SimpleBus, TaskBus
7
8
  from cq._core.routing.handler import (
@@ -54,9 +55,16 @@ class Router:
54
55
  def query_types(self) -> KeysView[type[Query]]:
55
56
  return self.__query_registry.message_types
56
57
 
58
+ def command_pipeline[T](self) -> ContextCommandPipeline[T]:
59
+ return ContextCommandPipeline(self.__di)
60
+
57
61
  def new_command_bus(self) -> Bus[Command, Any]:
58
62
  bus = SimpleBus(self.__command_registry)
59
- bus.add_middlewares(self.__di.command_scope())
63
+
64
+ command_scope_middleware = self.__di.command_scope()
65
+ if command_scope_middleware is not None:
66
+ bus.add_middlewares(command_scope_middleware)
67
+
60
68
  return bus
61
69
 
62
70
  def new_event_bus(self) -> Bus[Event, None]:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: python-cq
3
- Version: 0.23.1
3
+ Version: 0.24.0
4
4
  Summary: CQRS library for async Python projects.
5
5
  Project-URL: Documentation, https://python-cq.remimd.dev
6
6
  Project-URL: Repository, https://github.com/100nm/python-cq
@@ -1,4 +1,4 @@
1
- cq/__init__.py,sha256=gN4nQM3HrA8FLrZ4u_AI-I9o9syhbLAr78lVfFb84c4,2076
1
+ cq/__init__.py,sha256=0HISWerIbqoHHk_ZTH43RBRN2fwt1X4KXPBuIj0WF60,1911
2
2
  cq/exceptions.py,sha256=lmIpWDbPPwdS9bAAKxUvampA1KKmB706wWaB2mKZyPc,111
3
3
  cq/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  cq/_core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -13,10 +13,10 @@ cq/_core/queuing/queues/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG
13
13
  cq/_core/queuing/queues/abc.py,sha256=XAKHNK6Ez20UWTo_WC5DysMR1h1O3c3gPvwj0TWzQQk,728
14
14
  cq/_core/queuing/queues/memory.py,sha256=8brPNzKVDiev4rWf3MDeV_eU8gsXpLgCws7jSgYvAMQ,1815
15
15
  cq/_core/routing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
- cq/_core/routing/command_pipeline.py,sha256=PvuCH6PW2zgXDM3s3KNzIYa9ZNjpnHwe_6lf9M2LIXE,1637
17
- cq/_core/routing/di.py,sha256=i3AJJV1vSb9ovg2IWub3t0xhDljK0VydAAxUj0a_ask,3414
16
+ cq/_core/routing/command_pipeline.py,sha256=30Au2tkuUUHNGaC4sZ9755cgIt_bbwG6hHD16FxqKpU,1844
17
+ cq/_core/routing/di.py,sha256=Bp5CTDb-KkNzVJ7ostYt7VHMo3WnoE5L67KuiOYdG50,3147
18
18
  cq/_core/routing/handler.py,sha256=K6sR30thqT1Zbu--HFt2MUwDxqXap2qLrfjO25DoyLU,7656
19
- cq/_core/routing/router.py,sha256=8x6HH7A4qxdbjhSmqx3Us27UqjwOHSGk_tt3HeqpG8A,2362
19
+ cq/_core/routing/router.py,sha256=s6xkFeBosOOTjh5CTwBF64uYu23TSzFRK67xlDjJvPI,2660
20
20
  cq/_core/routing/dispatchers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
21
  cq/_core/routing/dispatchers/abc.py,sha256=PKHHrs4lmK5nDAOLI97X_hueHnmarZKFXXX51MCpJDw,1268
22
22
  cq/_core/routing/dispatchers/bus.py,sha256=ZQ1nvSuhLgEvqGMPIgKgWdkKueVzwrTDWeK07TfE57g,3429
@@ -28,7 +28,7 @@ cq/middlewares/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
28
  cq/middlewares/contextlib.py,sha256=_kwbXteGADGuzD-o2pPoPWOeTKiXcPCNuDmpG-f-YnY,875
29
29
  cq/middlewares/exc.py,sha256=ecAMoksj6B4osySSZ9g_cBR35_tiABQdpII-Drxkz44,1604
30
30
  cq/middlewares/retry.py,sha256=L6X_Wa2TZ0IYNXmi8oexTXQyM_lkjJt5Ew4D-2VzwBY,957
31
- python_cq-0.23.1.dist-info/METADATA,sha256=Uk2HoqN2q3KnMExb1O7lLFVuM5FNEaWbfY9PBdIebiw,4562
32
- python_cq-0.23.1.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
33
- python_cq-0.23.1.dist-info/licenses/LICENSE,sha256=oC77BOa9kaaQni5rW-Z-ytz3E5h4EVg248BHg9UFgyg,1063
34
- python_cq-0.23.1.dist-info/RECORD,,
31
+ python_cq-0.24.0.dist-info/METADATA,sha256=6ENGI4KWPmBJUKAlUXI45DcYHVIWA3qGogeHqgWY0MQ,4562
32
+ python_cq-0.24.0.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
33
+ python_cq-0.24.0.dist-info/licenses/LICENSE,sha256=oC77BOa9kaaQni5rW-Z-ytz3E5h4EVg248BHg9UFgyg,1063
34
+ python_cq-0.24.0.dist-info/RECORD,,