python-cq 0.22.0__tar.gz → 0.23.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.
- {python_cq-0.22.0 → python_cq-0.23.0}/PKG-INFO +7 -2
- {python_cq-0.22.0 → python_cq-0.23.0}/cq/__init__.py +27 -24
- {python_cq-0.22.0 → python_cq-0.23.0}/cq/_core/message.py +1 -1
- {python_cq-0.22.0 → python_cq-0.23.0}/cq/_core/middleware.py +2 -2
- {python_cq-0.22.0/cq/_core → python_cq-0.23.0/cq/_core/queuing}/pump.py +1 -1
- {python_cq-0.22.0/cq/_core → python_cq-0.23.0/cq/_core/queuing}/queues/abc.py +3 -2
- {python_cq-0.22.0/cq/_core → python_cq-0.23.0/cq/_core/queuing}/queues/memory.py +6 -6
- python_cq-0.22.0/cq/_core/pipetools.py → python_cq-0.23.0/cq/_core/routing/command_pipeline.py +5 -5
- {python_cq-0.22.0/cq/_core → python_cq-0.23.0/cq/_core/routing}/dispatchers/bus.py +5 -5
- {python_cq-0.22.0/cq/_core → python_cq-0.23.0/cq/_core/routing}/dispatchers/lazy.py +2 -2
- {python_cq-0.22.0/cq/_core → python_cq-0.23.0/cq/_core/routing}/dispatchers/pipe.py +1 -1
- {python_cq-0.22.0/cq/_core → python_cq-0.23.0/cq/_core/routing}/handler.py +2 -2
- python_cq-0.22.0/cq/_core/cq.py → python_cq-0.23.0/cq/_core/routing/router.py +7 -7
- {python_cq-0.22.0 → python_cq-0.23.0}/cq/ext/injection.py +3 -3
- python_cq-0.23.0/cq/middlewares/__init__.py +0 -0
- {python_cq-0.22.0 → python_cq-0.23.0}/cq/middlewares/contextlib.py +4 -3
- python_cq-0.23.0/cq/py.typed +0 -0
- {python_cq-0.22.0 → python_cq-0.23.0}/docs/index.md +4 -0
- {python_cq-0.22.0 → python_cq-0.23.0}/pyproject.toml +2 -1
- {python_cq-0.22.0 → python_cq-0.23.0}/.gitignore +0 -0
- {python_cq-0.22.0 → python_cq-0.23.0}/LICENSE +0 -0
- {python_cq-0.22.0 → python_cq-0.23.0}/cq/_core/__init__.py +0 -0
- {python_cq-0.22.0 → python_cq-0.23.0}/cq/_core/common/__init__.py +0 -0
- {python_cq-0.22.0 → python_cq-0.23.0}/cq/_core/common/typing.py +0 -0
- {python_cq-0.22.0/cq/_core/dispatchers → python_cq-0.23.0/cq/_core/queuing}/__init__.py +0 -0
- {python_cq-0.22.0/cq/_core → python_cq-0.23.0/cq/_core/queuing}/queues/__init__.py +0 -0
- {python_cq-0.22.0 → python_cq-0.23.0}/cq/_core/related_events.py +0 -0
- {python_cq-0.22.0/cq/ext → python_cq-0.23.0/cq/_core/routing}/__init__.py +0 -0
- {python_cq-0.22.0/cq/_core → python_cq-0.23.0/cq/_core/routing}/di.py +0 -0
- {python_cq-0.22.0/cq/middlewares → python_cq-0.23.0/cq/_core/routing/dispatchers}/__init__.py +0 -0
- {python_cq-0.22.0/cq/_core → python_cq-0.23.0/cq/_core/routing}/dispatchers/abc.py +0 -0
- {python_cq-0.22.0 → python_cq-0.23.0}/cq/exceptions.py +0 -0
- /python_cq-0.22.0/cq/py.typed → /python_cq-0.23.0/cq/ext/__init__.py +0 -0
- {python_cq-0.22.0 → python_cq-0.23.0}/cq/middlewares/exc.py +0 -0
- {python_cq-0.22.0 → python_cq-0.23.0}/cq/middlewares/retry.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: python-cq
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.23.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
|
|
@@ -18,6 +18,7 @@ Classifier: Programming Language :: Python :: 3 :: Only
|
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.12
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.13
|
|
20
20
|
Classifier: Programming Language :: Python :: 3.14
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
21
22
|
Classifier: Topic :: Software Development :: Libraries
|
|
22
23
|
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
23
24
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
@@ -80,23 +81,27 @@ from cq import CommandBus, command_handler
|
|
|
80
81
|
from dataclasses import dataclass
|
|
81
82
|
from injection import inject
|
|
82
83
|
|
|
84
|
+
|
|
83
85
|
@dataclass
|
|
84
86
|
class CreateUserCommand:
|
|
85
87
|
name: str
|
|
86
88
|
email: str
|
|
87
89
|
|
|
90
|
+
|
|
88
91
|
@command_handler
|
|
89
92
|
class CreateUserHandler:
|
|
90
93
|
async def handle(self, command: CreateUserCommand) -> int:
|
|
91
94
|
# ... persist the user, return its id
|
|
92
95
|
return 42
|
|
93
96
|
|
|
97
|
+
|
|
94
98
|
@inject
|
|
95
99
|
async def main(bus: CommandBus[int]) -> None:
|
|
96
100
|
command = CreateUserCommand(name="Ada", email="ada@example.com")
|
|
97
101
|
user_id = await bus.dispatch(command)
|
|
98
102
|
print(f"Created user {user_id}")
|
|
99
103
|
|
|
104
|
+
|
|
100
105
|
asyncio.run(main())
|
|
101
106
|
```
|
|
102
107
|
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
from ._core.cq import CQ
|
|
2
|
-
from ._core.di import DIAdapter
|
|
3
|
-
from ._core.di import NoDI as _NoDI
|
|
4
|
-
from ._core.dispatchers.abc import Dispatcher
|
|
5
|
-
from ._core.dispatchers.bus import Bus
|
|
6
|
-
from ._core.dispatchers.pipe import ContextPipeline, Pipe
|
|
7
1
|
from ._core.message import (
|
|
8
2
|
AnyCommandBus,
|
|
9
3
|
Command,
|
|
@@ -14,25 +8,30 @@ from ._core.message import (
|
|
|
14
8
|
QueryBus,
|
|
15
9
|
)
|
|
16
10
|
from ._core.middleware import Middleware, MiddlewareResult, resolve_handler_source
|
|
17
|
-
from ._core.
|
|
18
|
-
from ._core.
|
|
19
|
-
from ._core.queues.
|
|
20
|
-
from ._core.queues.memory import MemoryQueue
|
|
11
|
+
from ._core.queuing.pump import Pump
|
|
12
|
+
from ._core.queuing.queues.abc import Consumer, Delivery, Producer, Queue
|
|
13
|
+
from ._core.queuing.queues.memory import MemoryQueue
|
|
21
14
|
from ._core.related_events import AnyIORelatedEvents, RelatedEvents
|
|
15
|
+
from ._core.routing.command_pipeline import (
|
|
16
|
+
ContextCommandPipeline as _ContextCommandPipeline,
|
|
17
|
+
)
|
|
18
|
+
from ._core.routing.di import DIAdapter
|
|
19
|
+
from ._core.routing.dispatchers.abc import Dispatcher
|
|
20
|
+
from ._core.routing.dispatchers.bus import Bus
|
|
21
|
+
from ._core.routing.dispatchers.pipe import ContextPipeline, Pipe
|
|
22
|
+
from ._core.routing.router import Router
|
|
22
23
|
|
|
23
24
|
__all__ = (
|
|
24
|
-
"__cq__",
|
|
25
25
|
"AnyCommandBus",
|
|
26
26
|
"AnyIORelatedEvents",
|
|
27
27
|
"Bus",
|
|
28
|
-
"CQ",
|
|
29
28
|
"Command",
|
|
30
29
|
"CommandBus",
|
|
31
30
|
"Consumer",
|
|
32
31
|
"ContextCommandPipeline",
|
|
33
32
|
"ContextPipeline",
|
|
34
|
-
"Delivery",
|
|
35
33
|
"DIAdapter",
|
|
34
|
+
"Delivery",
|
|
36
35
|
"Dispatcher",
|
|
37
36
|
"Event",
|
|
38
37
|
"EventBus",
|
|
@@ -46,6 +45,8 @@ __all__ = (
|
|
|
46
45
|
"QueryBus",
|
|
47
46
|
"Queue",
|
|
48
47
|
"RelatedEvents",
|
|
48
|
+
"Router",
|
|
49
|
+
"__router__",
|
|
49
50
|
"command_handler",
|
|
50
51
|
"event_handler",
|
|
51
52
|
"new_command_bus",
|
|
@@ -55,28 +56,30 @@ __all__ = (
|
|
|
55
56
|
"resolve_handler_source",
|
|
56
57
|
)
|
|
57
58
|
|
|
59
|
+
|
|
58
60
|
try:
|
|
59
|
-
from .ext.injection import InjectionAdapter
|
|
61
|
+
from .ext.injection import InjectionAdapter
|
|
60
62
|
|
|
61
63
|
except ImportError: # pragma: no cover
|
|
62
|
-
|
|
64
|
+
__router__ = Router()
|
|
63
65
|
|
|
64
66
|
else:
|
|
65
|
-
|
|
67
|
+
__router__ = Router(InjectionAdapter())
|
|
68
|
+
del InjectionAdapter
|
|
66
69
|
|
|
67
|
-
|
|
70
|
+
__router__.register_defaults()
|
|
68
71
|
|
|
69
|
-
command_handler =
|
|
70
|
-
event_handler =
|
|
71
|
-
query_handler =
|
|
72
|
+
command_handler = __router__.command_handler
|
|
73
|
+
event_handler = __router__.event_handler
|
|
74
|
+
query_handler = __router__.query_handler
|
|
72
75
|
|
|
73
|
-
new_command_bus =
|
|
74
|
-
new_event_bus =
|
|
75
|
-
new_query_bus =
|
|
76
|
+
new_command_bus = __router__.new_command_bus
|
|
77
|
+
new_event_bus = __router__.new_event_bus
|
|
78
|
+
new_query_bus = __router__.new_query_bus
|
|
76
79
|
|
|
77
80
|
|
|
78
81
|
class ContextCommandPipeline[C: Command](_ContextCommandPipeline[C]):
|
|
79
82
|
__slots__ = ()
|
|
80
83
|
|
|
81
|
-
def __init__(self, di: DIAdapter =
|
|
84
|
+
def __init__(self, di: DIAdapter = __router__.di) -> None:
|
|
82
85
|
super().__init__(di)
|
|
@@ -3,7 +3,7 @@ from dataclasses import dataclass, field
|
|
|
3
3
|
from inspect import isasyncgenfunction
|
|
4
4
|
from typing import Any, Concatenate, Self, TypeGuard
|
|
5
5
|
|
|
6
|
-
from cq._core.handler import HandleFunction, HandlerType
|
|
6
|
+
from cq._core.routing.handler import HandleFunction, HandlerType
|
|
7
7
|
from cq.exceptions import MiddlewareError
|
|
8
8
|
|
|
9
9
|
type MiddlewareResult[T] = AsyncGenerator[None, T]
|
|
@@ -98,7 +98,7 @@ class _GeneratorMiddleware[**P, T]:
|
|
|
98
98
|
while True:
|
|
99
99
|
try:
|
|
100
100
|
value = await call_next(*args, **kwargs)
|
|
101
|
-
except BaseException as exc:
|
|
101
|
+
except BaseException as exc: # noqa: BLE001
|
|
102
102
|
await generator.athrow(exc)
|
|
103
103
|
else:
|
|
104
104
|
await generator.asend(value)
|
|
@@ -6,7 +6,7 @@ from typing import Any, Self
|
|
|
6
6
|
import anyio
|
|
7
7
|
|
|
8
8
|
from cq._core.middleware import Middleware, MiddlewareGroup
|
|
9
|
-
from cq._core.queues.abc import Consumer
|
|
9
|
+
from cq._core.queuing.queues.abc import Consumer
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
@dataclass(repr=False, eq=False, frozen=True, slots=True)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from abc import abstractmethod
|
|
2
2
|
from collections.abc import AsyncIterable
|
|
3
|
-
from
|
|
3
|
+
from contextlib import AbstractAsyncContextManager
|
|
4
|
+
from typing import Protocol, runtime_checkable
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
@runtime_checkable
|
|
@@ -16,7 +17,7 @@ class Producer[T](Protocol):
|
|
|
16
17
|
|
|
17
18
|
|
|
18
19
|
@runtime_checkable
|
|
19
|
-
class Delivery[T](
|
|
20
|
+
class Delivery[T](AbstractAsyncContextManager[T], Protocol):
|
|
20
21
|
__slots__ = ()
|
|
21
22
|
|
|
22
23
|
|
|
@@ -7,8 +7,8 @@ import anyio
|
|
|
7
7
|
from anyio.abc import ObjectReceiveStream, ObjectSendStream
|
|
8
8
|
|
|
9
9
|
from cq._core.middleware import Middleware
|
|
10
|
-
from cq._core.pump import Pump
|
|
11
|
-
from cq._core.queues.abc import Delivery, Queue
|
|
10
|
+
from cq._core.queuing.pump import Pump
|
|
11
|
+
from cq._core.queuing.queues.abc import Delivery, Queue
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
class MemoryQueue[T](Queue[T]):
|
|
@@ -17,7 +17,7 @@ class MemoryQueue[T](Queue[T]):
|
|
|
17
17
|
__consumer: ObjectReceiveStream[T]
|
|
18
18
|
__producer: ObjectSendStream[T]
|
|
19
19
|
|
|
20
|
-
def __init__(self, maxsize:
|
|
20
|
+
def __init__(self, maxsize: float = 0) -> None:
|
|
21
21
|
self.__producer, self.__consumer = anyio.create_memory_object_stream(maxsize)
|
|
22
22
|
|
|
23
23
|
async def __aenter__(self) -> Self:
|
|
@@ -51,10 +51,10 @@ class MemoryQueue[T](Queue[T]):
|
|
|
51
51
|
async with (
|
|
52
52
|
Pump(self, dispatcher, fail_silently)
|
|
53
53
|
.add_middlewares(*middlewares)
|
|
54
|
-
.draining(concurrency=concurrency, graceful=True)
|
|
54
|
+
.draining(concurrency=concurrency, graceful=True),
|
|
55
|
+
self,
|
|
55
56
|
):
|
|
56
|
-
|
|
57
|
-
yield self
|
|
57
|
+
yield self
|
|
58
58
|
|
|
59
59
|
async def send(self, message: T, /) -> None:
|
|
60
60
|
await self.__producer.send(message)
|
python_cq-0.22.0/cq/_core/pipetools.py → python_cq-0.23.0/cq/_core/routing/command_pipeline.py
RENAMED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
from typing import TYPE_CHECKING, Any, Self, overload
|
|
2
2
|
|
|
3
|
-
from cq import Dispatcher
|
|
4
3
|
from cq._core.common.typing import Decorator
|
|
5
|
-
from cq._core.
|
|
6
|
-
from cq._core.
|
|
7
|
-
from cq._core.dispatchers.
|
|
4
|
+
from cq._core.message import Command, CommandBus, Query, QueryBus
|
|
5
|
+
from cq._core.routing.di import DIAdapter
|
|
6
|
+
from cq._core.routing.dispatchers.abc import Dispatcher
|
|
7
|
+
from cq._core.routing.dispatchers.lazy import LazyDispatcher
|
|
8
|
+
from cq._core.routing.dispatchers.pipe import (
|
|
8
9
|
ContextPipeline,
|
|
9
10
|
ConvertMethod,
|
|
10
11
|
ConvertMethodAsync,
|
|
11
12
|
ConvertMethodSync,
|
|
12
13
|
)
|
|
13
|
-
from cq._core.message import Command, CommandBus, Query, QueryBus
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
class ContextCommandPipeline[C: Command](ContextPipeline[C]):
|
|
@@ -5,15 +5,15 @@ from typing import Any, Protocol, Self, runtime_checkable
|
|
|
5
5
|
import anyio
|
|
6
6
|
from anyio.abc import TaskGroup
|
|
7
7
|
|
|
8
|
-
from cq._core.
|
|
9
|
-
from cq._core.
|
|
8
|
+
from cq._core.middleware import Middleware
|
|
9
|
+
from cq._core.routing.dispatchers.abc import BaseDispatcher, Dispatcher
|
|
10
|
+
from cq._core.routing.handler import (
|
|
10
11
|
HandleFunction,
|
|
11
12
|
HandlerFactory,
|
|
12
13
|
HandlerRegistry,
|
|
13
14
|
MultipleHandlerRegistry,
|
|
14
15
|
SingleHandlerRegistry,
|
|
15
16
|
)
|
|
16
|
-
from cq._core.middleware import Middleware
|
|
17
17
|
|
|
18
18
|
type Listener[T] = Callable[[T], Awaitable[Any]]
|
|
19
19
|
|
|
@@ -82,7 +82,7 @@ class SimpleBus[I, O](BaseBus[I, O]):
|
|
|
82
82
|
async with anyio.create_task_group() as task_group:
|
|
83
83
|
self._trigger_listeners(message, task_group)
|
|
84
84
|
|
|
85
|
-
for handler in self._handlers_from(
|
|
85
|
+
for handler in self._handlers_from(message.__class__):
|
|
86
86
|
return await self._invoke(handler, message, handler.fail_silently)
|
|
87
87
|
|
|
88
88
|
return NotImplemented
|
|
@@ -98,7 +98,7 @@ class TaskBus[I](BaseBus[I, None]):
|
|
|
98
98
|
async with anyio.create_task_group() as task_group:
|
|
99
99
|
self._trigger_listeners(message, task_group)
|
|
100
100
|
|
|
101
|
-
for handler in self._handlers_from(
|
|
101
|
+
for handler in self._handlers_from(message.__class__):
|
|
102
102
|
task_group.start_soon(
|
|
103
103
|
self._invoke,
|
|
104
104
|
handler,
|
|
@@ -2,8 +2,8 @@ from collections.abc import Awaitable, Callable
|
|
|
2
2
|
from types import GenericAlias
|
|
3
3
|
from typing import TypeAliasType
|
|
4
4
|
|
|
5
|
-
from cq._core.di import DIAdapter
|
|
6
|
-
from cq._core.dispatchers.abc import Dispatcher
|
|
5
|
+
from cq._core.routing.di import DIAdapter
|
|
6
|
+
from cq._core.routing.dispatchers.abc import Dispatcher
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class LazyDispatcher[I, O](Dispatcher[I, O]):
|
|
@@ -14,8 +14,8 @@ from typing import (
|
|
|
14
14
|
)
|
|
15
15
|
|
|
16
16
|
from cq._core.common.typing import Decorator, Method
|
|
17
|
-
from cq._core.dispatchers.abc import BaseDispatcher, Dispatcher
|
|
18
17
|
from cq._core.middleware import Middleware, MiddlewareGroup
|
|
18
|
+
from cq._core.routing.dispatchers.abc import BaseDispatcher, Dispatcher
|
|
19
19
|
|
|
20
20
|
type ConvertAsync[**P, I, O] = Callable[Concatenate[O, P], Awaitable[I]]
|
|
21
21
|
type ConvertSync[**P, I, O] = Callable[Concatenate[O, P], I]
|
|
@@ -10,7 +10,7 @@ from typing import TYPE_CHECKING, Any, Protocol, Self, overload, runtime_checkab
|
|
|
10
10
|
from type_analyzer import MatchingTypesConfig, iter_matching_types, matching_types
|
|
11
11
|
|
|
12
12
|
from cq._core.common.typing import Decorator
|
|
13
|
-
from cq._core.di import DIAdapter, NoDI
|
|
13
|
+
from cq._core.routing.di import DIAdapter, NoDI
|
|
14
14
|
|
|
15
15
|
type HandlerType[**P, T] = type[Handler[P, T]]
|
|
16
16
|
type HandlerFactory[**P, T] = Callable[..., Awaitable[Handler[P, T]]]
|
|
@@ -183,7 +183,7 @@ class HandlerDecorator[I, O]:
|
|
|
183
183
|
and issubclass(message_or_handler_type, Handler)
|
|
184
184
|
):
|
|
185
185
|
return self.__decorator(
|
|
186
|
-
message_or_handler_type,
|
|
186
|
+
message_or_handler_type, # type: ignore[arg-type]
|
|
187
187
|
fail_silently=fail_silently,
|
|
188
188
|
)
|
|
189
189
|
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
from collections.abc import KeysView
|
|
2
2
|
from typing import Any, Self
|
|
3
3
|
|
|
4
|
-
from cq._core.
|
|
5
|
-
from cq._core.
|
|
6
|
-
from cq._core.
|
|
4
|
+
from cq._core.message import Command, Event, Query
|
|
5
|
+
from cq._core.routing.di import DIAdapter, NoDI
|
|
6
|
+
from cq._core.routing.dispatchers.bus import Bus, SimpleBus, TaskBus
|
|
7
|
+
from cq._core.routing.handler import (
|
|
7
8
|
HandlerDecorator,
|
|
8
9
|
HandlerRegistry,
|
|
9
10
|
MultipleHandlerRegistry,
|
|
10
11
|
SingleHandlerRegistry,
|
|
11
12
|
)
|
|
12
|
-
from cq._core.message import Command, Event, Query
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
class
|
|
15
|
+
class Router:
|
|
16
16
|
__slots__ = ("__command_registry", "__di", "__event_registry", "__query_registry")
|
|
17
17
|
|
|
18
18
|
__command_registry: HandlerRegistry[Command, Any]
|
|
@@ -20,8 +20,8 @@ class CQ:
|
|
|
20
20
|
__event_registry: HandlerRegistry[Event, Any]
|
|
21
21
|
__query_registry: HandlerRegistry[Query, Any]
|
|
22
22
|
|
|
23
|
-
def __init__(self, di: DIAdapter, /) -> None:
|
|
24
|
-
self.__di = di
|
|
23
|
+
def __init__(self, di: DIAdapter | None = None, /) -> None:
|
|
24
|
+
self.__di = di or NoDI()
|
|
25
25
|
self.__command_registry = SingleHandlerRegistry()
|
|
26
26
|
self.__event_registry = MultipleHandlerRegistry()
|
|
27
27
|
self.__query_registry = SingleHandlerRegistry()
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
from collections.abc import AsyncIterator
|
|
1
|
+
from collections.abc import AsyncIterator, Awaitable, Callable
|
|
2
2
|
from contextlib import AsyncExitStack
|
|
3
3
|
from dataclasses import dataclass, field
|
|
4
4
|
from enum import StrEnum
|
|
5
|
-
from typing import Any
|
|
5
|
+
from typing import Any
|
|
6
6
|
|
|
7
7
|
from injection import Module, adefine_scope, mod
|
|
8
8
|
from injection.exceptions import ScopeAlreadyDefinedError
|
|
9
9
|
|
|
10
|
-
from cq._core.di import DIAdapter
|
|
11
10
|
from cq._core.message import Command, CommandBus, EventBus, QueryBus
|
|
12
11
|
from cq._core.middleware import Middleware, MiddlewareResult
|
|
13
12
|
from cq._core.related_events import AnyIORelatedEvents, RelatedEvents
|
|
13
|
+
from cq._core.routing.di import DIAdapter
|
|
14
14
|
|
|
15
15
|
__all__ = ("CQScope", "InjectionAdapter", "InjectionScopeMiddleware")
|
|
16
16
|
|
|
File without changes
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
from contextlib import AbstractAsyncContextManager, AbstractContextManager
|
|
3
4
|
from dataclasses import dataclass
|
|
4
|
-
from typing import TYPE_CHECKING, Any
|
|
5
|
+
from typing import TYPE_CHECKING, Any
|
|
5
6
|
|
|
6
7
|
if TYPE_CHECKING: # pragma: no cover
|
|
7
8
|
from cq import MiddlewareResult
|
|
@@ -11,7 +12,7 @@ __all__ = ("AsyncContextManagerMiddleware", "ContextManagerMiddleware")
|
|
|
11
12
|
|
|
12
13
|
@dataclass(repr=False, eq=False, frozen=True, slots=True)
|
|
13
14
|
class AsyncContextManagerMiddleware:
|
|
14
|
-
context:
|
|
15
|
+
context: AbstractAsyncContextManager[Any]
|
|
15
16
|
|
|
16
17
|
async def __call__(self, /, *args: Any, **kwargs: Any) -> MiddlewareResult[Any]:
|
|
17
18
|
async with self.context:
|
|
@@ -20,7 +21,7 @@ class AsyncContextManagerMiddleware:
|
|
|
20
21
|
|
|
21
22
|
@dataclass(repr=False, eq=False, frozen=True, slots=True)
|
|
22
23
|
class ContextManagerMiddleware:
|
|
23
|
-
context:
|
|
24
|
+
context: AbstractContextManager[Any]
|
|
24
25
|
|
|
25
26
|
async def __call__(self, /, *args: Any, **kwargs: Any) -> MiddlewareResult[Any]:
|
|
26
27
|
with self.context:
|
|
File without changes
|
|
@@ -49,23 +49,27 @@ from cq import CommandBus, command_handler
|
|
|
49
49
|
from dataclasses import dataclass
|
|
50
50
|
from injection import inject
|
|
51
51
|
|
|
52
|
+
|
|
52
53
|
@dataclass
|
|
53
54
|
class CreateUserCommand:
|
|
54
55
|
name: str
|
|
55
56
|
email: str
|
|
56
57
|
|
|
58
|
+
|
|
57
59
|
@command_handler
|
|
58
60
|
class CreateUserHandler:
|
|
59
61
|
async def handle(self, command: CreateUserCommand) -> int:
|
|
60
62
|
# ... persist the user, return its id
|
|
61
63
|
return 42
|
|
62
64
|
|
|
65
|
+
|
|
63
66
|
@inject
|
|
64
67
|
async def main(bus: CommandBus[int]) -> None:
|
|
65
68
|
command = CreateUserCommand(name="Ada", email="ada@example.com")
|
|
66
69
|
user_id = await bus.dispatch(command)
|
|
67
70
|
print(f"Created user {user_id}")
|
|
68
71
|
|
|
72
|
+
|
|
69
73
|
asyncio.run(main())
|
|
70
74
|
```
|
|
71
75
|
|
|
@@ -20,7 +20,7 @@ test = [
|
|
|
20
20
|
|
|
21
21
|
[project]
|
|
22
22
|
name = "python-cq"
|
|
23
|
-
version = "0.
|
|
23
|
+
version = "0.23.0"
|
|
24
24
|
description = "CQRS library for async Python projects."
|
|
25
25
|
license = "MIT"
|
|
26
26
|
license-files = ["LICENSE"]
|
|
@@ -39,6 +39,7 @@ classifiers = [
|
|
|
39
39
|
"Programming Language :: Python :: 3.12",
|
|
40
40
|
"Programming Language :: Python :: 3.13",
|
|
41
41
|
"Programming Language :: Python :: 3.14",
|
|
42
|
+
"Programming Language :: Python :: 3.15",
|
|
42
43
|
"Operating System :: OS Independent",
|
|
43
44
|
"Intended Audience :: Developers",
|
|
44
45
|
"Natural Language :: English",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_cq-0.22.0/cq/middlewares → python_cq-0.23.0/cq/_core/routing/dispatchers}/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|