python-cq 0.9.0__tar.gz → 0.10.0__tar.gz

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.
Files changed (26) hide show
  1. {python_cq-0.9.0 → python_cq-0.10.0}/PKG-INFO +1 -1
  2. {python_cq-0.9.0 → python_cq-0.10.0}/cq/__init__.py +3 -2
  3. {python_cq-0.9.0 → python_cq-0.10.0}/cq/_core/dispatcher/base.py +6 -1
  4. {python_cq-0.9.0 → python_cq-0.10.0}/cq/_core/dispatcher/bus.py +7 -2
  5. {python_cq-0.9.0 → python_cq-0.10.0}/cq/_core/handler.py +2 -2
  6. python_cq-0.10.0/cq/ext/fastapi.py +73 -0
  7. {python_cq-0.9.0 → python_cq-0.10.0}/pyproject.toml +1 -1
  8. python_cq-0.9.0/cq/_core/defer.py +0 -10
  9. python_cq-0.9.0/cq/ext/fastapi.py +0 -44
  10. python_cq-0.9.0/cq/ext/fastapi.pyi +0 -5
  11. {python_cq-0.9.0 → python_cq-0.10.0}/.gitignore +0 -0
  12. {python_cq-0.9.0 → python_cq-0.10.0}/LICENSE +0 -0
  13. {python_cq-0.9.0 → python_cq-0.10.0}/README.md +0 -0
  14. {python_cq-0.9.0 → python_cq-0.10.0}/cq/_core/__init__.py +0 -0
  15. {python_cq-0.9.0 → python_cq-0.10.0}/cq/_core/dispatcher/__init__.py +0 -0
  16. {python_cq-0.9.0 → python_cq-0.10.0}/cq/_core/dispatcher/pipe.py +0 -0
  17. {python_cq-0.9.0 → python_cq-0.10.0}/cq/_core/message.py +0 -0
  18. {python_cq-0.9.0 → python_cq-0.10.0}/cq/_core/middleware.py +0 -0
  19. {python_cq-0.9.0 → python_cq-0.10.0}/cq/_core/related_events.py +0 -0
  20. {python_cq-0.9.0 → python_cq-0.10.0}/cq/_core/scope.py +0 -0
  21. {python_cq-0.9.0 → python_cq-0.10.0}/cq/exceptions.py +0 -0
  22. {python_cq-0.9.0 → python_cq-0.10.0}/cq/ext/__init__.py +0 -0
  23. {python_cq-0.9.0 → python_cq-0.10.0}/cq/middlewares/__init__.py +0 -0
  24. {python_cq-0.9.0 → python_cq-0.10.0}/cq/middlewares/retry.py +0 -0
  25. {python_cq-0.9.0 → python_cq-0.10.0}/cq/middlewares/scope.py +0 -0
  26. {python_cq-0.9.0 → python_cq-0.10.0}/cq/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-cq
3
- Version: 0.9.0
3
+ Version: 0.10.0
4
4
  Summary: Lightweight CQRS library for async Python projects.
5
5
  Project-URL: Repository, https://github.com/100nm/python-cq
6
6
  Author: remimd
@@ -1,4 +1,4 @@
1
- from ._core.defer import DeferredBus
1
+ from ._core.dispatcher.base import DeferredDispatcher, Dispatcher
2
2
  from ._core.dispatcher.bus import Bus
3
3
  from ._core.dispatcher.pipe import Pipe
4
4
  from ._core.message import (
@@ -26,7 +26,8 @@ __all__ = (
26
26
  "CQScope",
27
27
  "Command",
28
28
  "CommandBus",
29
- "DeferredBus",
29
+ "DeferredDispatcher",
30
+ "Dispatcher",
30
31
  "Event",
31
32
  "EventBus",
32
33
  "Middleware",
@@ -13,8 +13,13 @@ class Dispatcher[I, O](Protocol):
13
13
  async def dispatch(self, input_value: I, /) -> O:
14
14
  raise NotImplementedError
15
15
 
16
+
17
+ @runtime_checkable
18
+ class DeferredDispatcher[I](Protocol):
19
+ __slots__ = ()
20
+
16
21
  @abstractmethod
17
- def add_middlewares(self, *middlewares: Middleware[[I], O]) -> Self:
22
+ async def defer(self, input_value: I, /) -> None:
18
23
  raise NotImplementedError
19
24
 
20
25
 
@@ -12,6 +12,7 @@ from cq._core.handler import (
12
12
  MultipleHandlerManager,
13
13
  SingleHandlerManager,
14
14
  )
15
+ from cq._core.middleware import Middleware
15
16
 
16
17
  type Listener[T] = Callable[[T], Awaitable[Any]]
17
18
 
@@ -21,11 +22,15 @@ class Bus[I, O](Dispatcher[I, O], Protocol):
21
22
  __slots__ = ()
22
23
 
23
24
  @abstractmethod
24
- def subscribe(self, input_type: type[I], factory: HandlerFactory[[I], O]) -> Self:
25
+ def add_listeners(self, *listeners: Listener[I]) -> Self:
25
26
  raise NotImplementedError
26
27
 
27
28
  @abstractmethod
28
- def add_listeners(self, *listeners: Listener[I]) -> Self:
29
+ def add_middlewares(self, *middlewares: Middleware[[I], O]) -> Self:
30
+ raise NotImplementedError
31
+
32
+ @abstractmethod
33
+ def subscribe(self, input_type: type[I], factory: HandlerFactory[[I], O]) -> Self:
29
34
  raise NotImplementedError
30
35
 
31
36
 
@@ -151,8 +151,8 @@ class HandlerDecorator[I, O]:
151
151
 
152
152
 
153
153
  def _resolve_input_type[I, O](handler_type: HandlerType[[I], O]) -> type[I]:
154
- fake_handle_method = handler_type.handle.__get__(NotImplemented)
155
- signature = inspect_signature(fake_handle_method, eval_str=True)
154
+ fake_method = handler_type.handle.__get__(NotImplemented, handler_type)
155
+ signature = inspect_signature(fake_method, eval_str=True)
156
156
 
157
157
  for parameter in signature.parameters.values():
158
158
  input_type = parameter.annotation
@@ -0,0 +1,73 @@
1
+ from dataclasses import dataclass
2
+ from typing import TYPE_CHECKING, Annotated, Any
3
+
4
+ from fastapi import BackgroundTasks, Depends
5
+ from injection.ext.fastapi import Inject
6
+
7
+ from cq import (
8
+ Command,
9
+ CommandBus,
10
+ DeferredDispatcher,
11
+ Dispatcher,
12
+ Event,
13
+ EventBus,
14
+ Query,
15
+ QueryBus,
16
+ )
17
+
18
+ __all__ = (
19
+ "DeferredCommandBus",
20
+ "DeferredEventBus",
21
+ "DeferredQueryBus",
22
+ "FastAPIDeferredDispatcher",
23
+ )
24
+
25
+
26
+ @dataclass(repr=False, eq=False, frozen=True, slots=True)
27
+ class FastAPIDeferredDispatcher[I](DeferredDispatcher[I]):
28
+ background_tasks: BackgroundTasks
29
+ dispatcher: Dispatcher[I, Any]
30
+
31
+ async def defer(self, input_value: I, /) -> None:
32
+ self.background_tasks.add_task(self.dispatcher.dispatch, input_value)
33
+
34
+
35
+ async def new_deferred_command_bus[T](
36
+ background_tasks: BackgroundTasks,
37
+ command_bus: Inject[CommandBus[T]],
38
+ ) -> DeferredDispatcher[Command]:
39
+ return FastAPIDeferredDispatcher(background_tasks, command_bus)
40
+
41
+
42
+ async def new_deferred_event_bus(
43
+ background_tasks: BackgroundTasks,
44
+ event_bus: Inject[EventBus],
45
+ ) -> DeferredDispatcher[Event]:
46
+ return FastAPIDeferredDispatcher(background_tasks, event_bus)
47
+
48
+
49
+ async def new_deferred_query_bus[T](
50
+ background_tasks: BackgroundTasks,
51
+ query_bus: Inject[QueryBus[T]],
52
+ ) -> DeferredDispatcher[Query]:
53
+ return FastAPIDeferredDispatcher(background_tasks, query_bus)
54
+
55
+
56
+ if TYPE_CHECKING:
57
+ type DeferredCommandBus = DeferredDispatcher[Command]
58
+ type DeferredEventBus = DeferredDispatcher[Event]
59
+ type DeferredQueryBus = DeferredDispatcher[Query]
60
+
61
+ else:
62
+ DeferredCommandBus = Annotated[
63
+ DeferredDispatcher[Command],
64
+ Depends(new_deferred_command_bus, use_cache=False),
65
+ ]
66
+ DeferredEventBus = Annotated[
67
+ DeferredDispatcher[Event],
68
+ Depends(new_deferred_event_bus, use_cache=False),
69
+ ]
70
+ DeferredQueryBus = Annotated[
71
+ DeferredDispatcher[Query],
72
+ Depends(new_deferred_query_bus, use_cache=False),
73
+ ]
@@ -23,7 +23,7 @@ test = [
23
23
 
24
24
  [project]
25
25
  name = "python-cq"
26
- version = "0.9.0"
26
+ version = "0.10.0"
27
27
  description = "Lightweight CQRS library for async Python projects."
28
28
  license = "MIT"
29
29
  license-files = ["LICENSE"]
@@ -1,10 +0,0 @@
1
- from abc import abstractmethod
2
- from typing import Protocol
3
-
4
-
5
- class DeferredBus[I](Protocol):
6
- __slots__ = ()
7
-
8
- @abstractmethod
9
- async def defer(self, input_value: I, /) -> None:
10
- raise NotImplementedError
@@ -1,44 +0,0 @@
1
- from dataclasses import dataclass
2
- from typing import Annotated, Any
3
-
4
- from fastapi import BackgroundTasks, Depends
5
- from injection.ext.fastapi import Inject
6
-
7
- from cq import Bus, Command, CommandBus, DeferredBus, Event, EventBus, Query, QueryBus
8
-
9
- __all__ = ("DeferredCommandBus", "DeferredEventBus", "DeferredQueryBus")
10
-
11
-
12
- @dataclass(repr=False, eq=False, frozen=True, slots=True)
13
- class FastAPIDeferredBus[I](DeferredBus[I]):
14
- background_tasks: BackgroundTasks
15
- bus: Bus[I, Any]
16
-
17
- async def defer(self, input_value: I, /) -> None:
18
- self.background_tasks.add_task(self.bus.dispatch, input_value)
19
-
20
-
21
- async def new_deferred_command_bus[T](
22
- background_tasks: BackgroundTasks,
23
- command_bus: Inject[CommandBus[T]],
24
- ) -> DeferredBus[Command]:
25
- return FastAPIDeferredBus(background_tasks, command_bus)
26
-
27
-
28
- async def new_deferred_event_bus(
29
- background_tasks: BackgroundTasks,
30
- event_bus: Inject[EventBus],
31
- ) -> DeferredBus[Event]:
32
- return FastAPIDeferredBus(background_tasks, event_bus)
33
-
34
-
35
- async def new_deferred_query_bus[T](
36
- background_tasks: BackgroundTasks,
37
- query_bus: Inject[QueryBus[T]],
38
- ) -> DeferredBus[Query]:
39
- return FastAPIDeferredBus(background_tasks, query_bus)
40
-
41
-
42
- DeferredCommandBus = Annotated[DeferredBus[Command], Depends(new_deferred_command_bus)]
43
- DeferredEventBus = Annotated[DeferredBus[Event], Depends(new_deferred_event_bus)]
44
- DeferredQueryBus = Annotated[DeferredBus[Query], Depends(new_deferred_query_bus)]
@@ -1,5 +0,0 @@
1
- from cq import Command, DeferredBus, Event, Query
2
-
3
- type DeferredCommandBus = DeferredBus[Command]
4
- type DeferredEventBus = DeferredBus[Event]
5
- type DeferredQueryBus = DeferredBus[Query]
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes