pymediate 0.1.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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 sina-al
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,238 @@
1
+ Metadata-Version: 2.4
2
+ Name: pymediate
3
+ Version: 0.1.0
4
+ Summary: A type-safe mediator pattern implementation for Python 3.12+
5
+ Keywords: mediator,cqrs,dependency-injection,type-safe,request-dispatch
6
+ Author: sina-al
7
+ Author-email: sina-al <27771210+sina-al@users.noreply.github.com>
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Programming Language :: Python :: 3.14
18
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
19
+ Classifier: Typing :: Typed
20
+ Requires-Dist: dependency-injector>=4.41.0 ; extra == 'di'
21
+ Requires-Python: >=3.12
22
+ Project-URL: Homepage, https://github.com/sina-al/pymediate
23
+ Project-URL: Documentation, https://sina-al.github.io/pymediate/
24
+ Project-URL: Repository, https://github.com/sina-al/pymediate
25
+ Project-URL: Issues, https://github.com/sina-al/pymediate/issues
26
+ Project-URL: Changelog, https://github.com/sina-al/pymediate/releases
27
+ Provides-Extra: di
28
+ Description-Content-Type: text/markdown
29
+
30
+ <p align="center">
31
+ <img src="https://github.com/sina-al/pymediate/blob/main/assets/logo.svg?raw=true" alt="PyMediate logo" width="400"><br><br>
32
+ <b>A type-safe request mediator for Python 3.12+</b><br><br>
33
+
34
+ <!-- Badges -->
35
+ <a href="https://github.com/sina-al/pymediate/actions/workflows/test.yml">
36
+ <img src="https://github.com/sina-al/pymediate/actions/workflows/test.yml/badge.svg" alt="Tests">
37
+ </a>
38
+ <a href="https://github.com/sina-al/pymediate/actions/workflows/code-quality.yml">
39
+ <img src="https://github.com/sina-al/pymediate/actions/workflows/code-quality.yml/badge.svg" alt="Code Quality">
40
+ </a>
41
+ <a href="https://www.python.org/downloads/">
42
+ <img src="https://img.shields.io/badge/python-3.12+-blue.svg" alt="Python 3.12+">
43
+ </a>
44
+ <a href="https://badge.fury.io/py/pymediate">
45
+ <img src="https://badge.fury.io/py/pymediate.svg" alt="PyPI version">
46
+ </a>
47
+ <a href="https://opensource.org/licenses/MIT">
48
+ <img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="MIT License">
49
+ </a>
50
+ </p>
51
+
52
+ ---
53
+
54
+ ## Features
55
+
56
+ - **Type Safety**: Full runtime validation with mypy support
57
+ - **Zero Convention**: No naming conventions - uses type inspection
58
+ - **Async/Await Support**: First-class async handlers and mediators via `pymediate.aio`
59
+ - **DI Ready**: Built-in dependency-injector integration
60
+ - **Dataclass Friendly**: Works seamlessly with `@dataclass` and Request[T] inheritance
61
+ - **Well Tested**: comprehensive test suite
62
+
63
+ ## Quick Example
64
+
65
+ ```python
66
+ from dataclasses import dataclass
67
+ from pymediate import Request, Handler, Mediator, Services
68
+
69
+ # Define response and request as pure dataclasses
70
+ @dataclass
71
+ class UserCreated:
72
+ user_id: int
73
+ username: str
74
+
75
+ @dataclass
76
+ class CreateUser(Request[UserCreated]):
77
+ username: str
78
+ email: str
79
+
80
+ # Handler automatically linked by type
81
+ class CreateUserHandler(Handler[CreateUser]):
82
+ def __call__(self, req: CreateUser) -> UserCreated:
83
+ return UserCreated(user_id=1, username=req.username)
84
+
85
+ # Set up and use
86
+ services = Services()
87
+ services.add(CreateUserHandler())
88
+ provider = services.provider()
89
+ mediator = Mediator(provider)
90
+
91
+ response = mediator.send(CreateUser(username="alice", email="alice@example.com"))
92
+ print(f"User {response.username} created with ID {response.user_id}")
93
+ ```
94
+
95
+ ### Async Support
96
+
97
+ PyMediate provides first-class async/await support through the `pymediate.aio` package:
98
+
99
+ ```python
100
+ import asyncio
101
+ from dataclasses import dataclass
102
+ from pymediate import Request, Services
103
+ from pymediate.aio import Handler, Mediator
104
+
105
+ @dataclass
106
+ class UserCreated:
107
+ user_id: int
108
+ username: str
109
+
110
+ @dataclass
111
+ class CreateUser(Request[UserCreated]):
112
+ username: str
113
+ email: str
114
+
115
+ class CreateUserHandler(Handler[CreateUser]):
116
+ async def __call__(self, req: CreateUser) -> UserCreated:
117
+ # Perform async operations
118
+ await asyncio.sleep(0.1) # Simulate async database call
119
+ return UserCreated(user_id=1, username=req.username)
120
+
121
+ async def main():
122
+ services = Services()
123
+ services.add(CreateUserHandler())
124
+ provider = services.provider()
125
+ mediator = Mediator(provider)
126
+
127
+ response = await mediator.send(CreateUser(username="alice", email="alice@example.com"))
128
+ print(f"User {response.username} created with ID {response.user_id}")
129
+
130
+ asyncio.run(main())
131
+ ```
132
+
133
+ **Key differences for async:**
134
+ - Import from `pymediate.aio` instead of `pymediate`
135
+ - Handler's `__call__` method must be `async def`
136
+ - Use `await mediator.send(...)` instead of `mediator.send(...)`
137
+ - Supports concurrent request handling with `asyncio.gather()`
138
+
139
+ ### Pipeline Behaviors
140
+
141
+ PyMediate supports pipeline behaviors (middleware) that automatically wrap request processing for cross-cutting concerns like logging, validation, caching, and more:
142
+
143
+ ```python
144
+ from pymediate import Request, PipelineBehavior
145
+
146
+ # Universal behavior - applies to all requests
147
+ class LoggingBehavior(PipelineBehavior[Request]):
148
+ def __call__(self, request, next):
149
+ print(f"Handling: {type(request).__name__}")
150
+ response = next()
151
+ print(f"Completed: {type(request).__name__}")
152
+ return response
153
+
154
+ # Selective behavior - only applies to CreateUser requests
155
+ class ValidationBehavior(PipelineBehavior[CreateUser]):
156
+ def __call__(self, request, next):
157
+ # Validate before processing
158
+ if not request.username:
159
+ raise ValueError("Username is required")
160
+ return next()
161
+
162
+ # Register behaviors and handlers
163
+ services = Services()
164
+ services.add(LoggingBehavior()) # Applied to ALL requests
165
+ services.add(ValidationBehavior()) # Only applied to CreateUser
166
+ services.add(CreateUserHandler())
167
+
168
+ mediator = Mediator(services.provider())
169
+
170
+ # Behaviors automatically wrap matching requests
171
+ response = mediator.send(CreateUser(username="alice", email="alice@example.com"))
172
+ # Output:
173
+ # Handling: CreateUser
174
+ # Completed: CreateUser
175
+ ```
176
+
177
+ Behaviors can be **universal** (`PipelineBehavior[Request]`) or **selective** (`PipelineBehavior[SpecificRequest]`), applying only to matching request types or mixins. They are resolved per request, respecting DI container scopes (Transient, Scoped, Singleton). See the [Pipeline Behaviors Guide](https://sina-al.github.io/pymediate/guide/pipeline-behaviors/) for more examples.
178
+
179
+ ## Installation
180
+
181
+ ```bash
182
+ # Core package
183
+ pip install pymediate
184
+
185
+ # With dependency injection support
186
+ pip install pymediate[di]
187
+ ```
188
+
189
+ ## Documentation
190
+
191
+ **[📚 Full Documentation](https://sina-al.github.io/pymediate/)**
192
+
193
+ - [Quick Start](https://sina-al.github.io/pymediate/getting-started/quick-start/)
194
+ - [User Guide](https://sina-al.github.io/pymediate/guide/requests-responses/)
195
+ - [Examples](https://sina-al.github.io/pymediate/examples/basic/)
196
+ - [API Reference](https://sina-al.github.io/pymediate/api/request/)
197
+
198
+ ## Development
199
+
200
+ ### Quick Start
201
+
202
+ ```bash
203
+ # Clone and install
204
+ git clone https://github.com/sina-al/pymediate.git
205
+ cd pymediate
206
+ uv sync --all-extras --group test
207
+
208
+ # Run tests
209
+ poe test
210
+
211
+ # Run all checks
212
+ poe check:all
213
+
214
+ # See all available tasks
215
+ poe
216
+ ```
217
+
218
+ ### Available Commands
219
+
220
+ PyMediate uses [Poe the Poet](https://poethepoet.natn.io/) for task running. Run `poe` to see all commands, or check [`tasks.toml`](tasks.toml).
221
+
222
+ > **Note:** `uv sync` alone only installs the default `dev` dependency group (ruff, mypy,
223
+ > poethepoet). Test dependencies (pytest and friends) live in the separate `test` group and
224
+ > won't be installed unless you pass `--group test` (or `--all-groups`) — otherwise `poe test`
225
+ > fails with `Failed to spawn: pytest`.
226
+
227
+ ## Requirements
228
+
229
+ - Python 3.12+
230
+ - Optional: `dependency-injector>=4.41.0` for DI support
231
+
232
+ ## Contributing
233
+
234
+ Contributions are welcome! Check the docs for guidelines.
235
+
236
+ ## License
237
+
238
+ MIT License - see [LICENSE](LICENSE) for details.
@@ -0,0 +1,209 @@
1
+ <p align="center">
2
+ <img src="https://github.com/sina-al/pymediate/blob/main/assets/logo.svg?raw=true" alt="PyMediate logo" width="400"><br><br>
3
+ <b>A type-safe request mediator for Python 3.12+</b><br><br>
4
+
5
+ <!-- Badges -->
6
+ <a href="https://github.com/sina-al/pymediate/actions/workflows/test.yml">
7
+ <img src="https://github.com/sina-al/pymediate/actions/workflows/test.yml/badge.svg" alt="Tests">
8
+ </a>
9
+ <a href="https://github.com/sina-al/pymediate/actions/workflows/code-quality.yml">
10
+ <img src="https://github.com/sina-al/pymediate/actions/workflows/code-quality.yml/badge.svg" alt="Code Quality">
11
+ </a>
12
+ <a href="https://www.python.org/downloads/">
13
+ <img src="https://img.shields.io/badge/python-3.12+-blue.svg" alt="Python 3.12+">
14
+ </a>
15
+ <a href="https://badge.fury.io/py/pymediate">
16
+ <img src="https://badge.fury.io/py/pymediate.svg" alt="PyPI version">
17
+ </a>
18
+ <a href="https://opensource.org/licenses/MIT">
19
+ <img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="MIT License">
20
+ </a>
21
+ </p>
22
+
23
+ ---
24
+
25
+ ## Features
26
+
27
+ - **Type Safety**: Full runtime validation with mypy support
28
+ - **Zero Convention**: No naming conventions - uses type inspection
29
+ - **Async/Await Support**: First-class async handlers and mediators via `pymediate.aio`
30
+ - **DI Ready**: Built-in dependency-injector integration
31
+ - **Dataclass Friendly**: Works seamlessly with `@dataclass` and Request[T] inheritance
32
+ - **Well Tested**: comprehensive test suite
33
+
34
+ ## Quick Example
35
+
36
+ ```python
37
+ from dataclasses import dataclass
38
+ from pymediate import Request, Handler, Mediator, Services
39
+
40
+ # Define response and request as pure dataclasses
41
+ @dataclass
42
+ class UserCreated:
43
+ user_id: int
44
+ username: str
45
+
46
+ @dataclass
47
+ class CreateUser(Request[UserCreated]):
48
+ username: str
49
+ email: str
50
+
51
+ # Handler automatically linked by type
52
+ class CreateUserHandler(Handler[CreateUser]):
53
+ def __call__(self, req: CreateUser) -> UserCreated:
54
+ return UserCreated(user_id=1, username=req.username)
55
+
56
+ # Set up and use
57
+ services = Services()
58
+ services.add(CreateUserHandler())
59
+ provider = services.provider()
60
+ mediator = Mediator(provider)
61
+
62
+ response = mediator.send(CreateUser(username="alice", email="alice@example.com"))
63
+ print(f"User {response.username} created with ID {response.user_id}")
64
+ ```
65
+
66
+ ### Async Support
67
+
68
+ PyMediate provides first-class async/await support through the `pymediate.aio` package:
69
+
70
+ ```python
71
+ import asyncio
72
+ from dataclasses import dataclass
73
+ from pymediate import Request, Services
74
+ from pymediate.aio import Handler, Mediator
75
+
76
+ @dataclass
77
+ class UserCreated:
78
+ user_id: int
79
+ username: str
80
+
81
+ @dataclass
82
+ class CreateUser(Request[UserCreated]):
83
+ username: str
84
+ email: str
85
+
86
+ class CreateUserHandler(Handler[CreateUser]):
87
+ async def __call__(self, req: CreateUser) -> UserCreated:
88
+ # Perform async operations
89
+ await asyncio.sleep(0.1) # Simulate async database call
90
+ return UserCreated(user_id=1, username=req.username)
91
+
92
+ async def main():
93
+ services = Services()
94
+ services.add(CreateUserHandler())
95
+ provider = services.provider()
96
+ mediator = Mediator(provider)
97
+
98
+ response = await mediator.send(CreateUser(username="alice", email="alice@example.com"))
99
+ print(f"User {response.username} created with ID {response.user_id}")
100
+
101
+ asyncio.run(main())
102
+ ```
103
+
104
+ **Key differences for async:**
105
+ - Import from `pymediate.aio` instead of `pymediate`
106
+ - Handler's `__call__` method must be `async def`
107
+ - Use `await mediator.send(...)` instead of `mediator.send(...)`
108
+ - Supports concurrent request handling with `asyncio.gather()`
109
+
110
+ ### Pipeline Behaviors
111
+
112
+ PyMediate supports pipeline behaviors (middleware) that automatically wrap request processing for cross-cutting concerns like logging, validation, caching, and more:
113
+
114
+ ```python
115
+ from pymediate import Request, PipelineBehavior
116
+
117
+ # Universal behavior - applies to all requests
118
+ class LoggingBehavior(PipelineBehavior[Request]):
119
+ def __call__(self, request, next):
120
+ print(f"Handling: {type(request).__name__}")
121
+ response = next()
122
+ print(f"Completed: {type(request).__name__}")
123
+ return response
124
+
125
+ # Selective behavior - only applies to CreateUser requests
126
+ class ValidationBehavior(PipelineBehavior[CreateUser]):
127
+ def __call__(self, request, next):
128
+ # Validate before processing
129
+ if not request.username:
130
+ raise ValueError("Username is required")
131
+ return next()
132
+
133
+ # Register behaviors and handlers
134
+ services = Services()
135
+ services.add(LoggingBehavior()) # Applied to ALL requests
136
+ services.add(ValidationBehavior()) # Only applied to CreateUser
137
+ services.add(CreateUserHandler())
138
+
139
+ mediator = Mediator(services.provider())
140
+
141
+ # Behaviors automatically wrap matching requests
142
+ response = mediator.send(CreateUser(username="alice", email="alice@example.com"))
143
+ # Output:
144
+ # Handling: CreateUser
145
+ # Completed: CreateUser
146
+ ```
147
+
148
+ Behaviors can be **universal** (`PipelineBehavior[Request]`) or **selective** (`PipelineBehavior[SpecificRequest]`), applying only to matching request types or mixins. They are resolved per request, respecting DI container scopes (Transient, Scoped, Singleton). See the [Pipeline Behaviors Guide](https://sina-al.github.io/pymediate/guide/pipeline-behaviors/) for more examples.
149
+
150
+ ## Installation
151
+
152
+ ```bash
153
+ # Core package
154
+ pip install pymediate
155
+
156
+ # With dependency injection support
157
+ pip install pymediate[di]
158
+ ```
159
+
160
+ ## Documentation
161
+
162
+ **[📚 Full Documentation](https://sina-al.github.io/pymediate/)**
163
+
164
+ - [Quick Start](https://sina-al.github.io/pymediate/getting-started/quick-start/)
165
+ - [User Guide](https://sina-al.github.io/pymediate/guide/requests-responses/)
166
+ - [Examples](https://sina-al.github.io/pymediate/examples/basic/)
167
+ - [API Reference](https://sina-al.github.io/pymediate/api/request/)
168
+
169
+ ## Development
170
+
171
+ ### Quick Start
172
+
173
+ ```bash
174
+ # Clone and install
175
+ git clone https://github.com/sina-al/pymediate.git
176
+ cd pymediate
177
+ uv sync --all-extras --group test
178
+
179
+ # Run tests
180
+ poe test
181
+
182
+ # Run all checks
183
+ poe check:all
184
+
185
+ # See all available tasks
186
+ poe
187
+ ```
188
+
189
+ ### Available Commands
190
+
191
+ PyMediate uses [Poe the Poet](https://poethepoet.natn.io/) for task running. Run `poe` to see all commands, or check [`tasks.toml`](tasks.toml).
192
+
193
+ > **Note:** `uv sync` alone only installs the default `dev` dependency group (ruff, mypy,
194
+ > poethepoet). Test dependencies (pytest and friends) live in the separate `test` group and
195
+ > won't be installed unless you pass `--group test` (or `--all-groups`) — otherwise `poe test`
196
+ > fails with `Failed to spawn: pytest`.
197
+
198
+ ## Requirements
199
+
200
+ - Python 3.12+
201
+ - Optional: `dependency-injector>=4.41.0` for DI support
202
+
203
+ ## Contributing
204
+
205
+ Contributions are welcome! Check the docs for guidelines.
206
+
207
+ ## License
208
+
209
+ MIT License - see [LICENSE](LICENSE) for details.
@@ -0,0 +1,79 @@
1
+ [project]
2
+ name = "pymediate"
3
+ version = "0.1.0"
4
+ description = "A type-safe mediator pattern implementation for Python 3.12+"
5
+ readme = "README.md"
6
+ authors = [
7
+ { name = "sina-al", email = "27771210+sina-al@users.noreply.github.com" },
8
+ ]
9
+ license = "MIT"
10
+ license-files = ["LICENSE"]
11
+ requires-python = ">=3.12"
12
+ dependencies = []
13
+ keywords = ["mediator", "cqrs", "dependency-injection", "type-safe", "request-dispatch"]
14
+ classifiers = [
15
+ "Development Status :: 4 - Beta",
16
+ "Intended Audience :: Developers",
17
+ "Operating System :: OS Independent",
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3 :: Only",
20
+ "Programming Language :: Python :: 3.12",
21
+ "Programming Language :: Python :: 3.13",
22
+ "Programming Language :: Python :: 3.14",
23
+ "Topic :: Software Development :: Libraries :: Python Modules",
24
+ "Typing :: Typed",
25
+ ]
26
+
27
+ [project.urls]
28
+ Homepage = "https://github.com/sina-al/pymediate"
29
+ Documentation = "https://sina-al.github.io/pymediate/"
30
+ Repository = "https://github.com/sina-al/pymediate"
31
+ Issues = "https://github.com/sina-al/pymediate/issues"
32
+ Changelog = "https://github.com/sina-al/pymediate/releases"
33
+
34
+ [project.optional-dependencies]
35
+ di = [
36
+ "dependency-injector>=4.41.0"
37
+ ]
38
+
39
+ [dependency-groups]
40
+ dev = [
41
+ "ruff>=0.8.4",
42
+ "poethepoet>=0.31.1",
43
+ "mypy>=1.13.0",
44
+ ]
45
+ test = [
46
+ "mypy>=1.13.0",
47
+ "pytest>=8.0.0",
48
+ "pytest-cov>=4.1.0",
49
+ "pytest-github-actions-annotate-failures>=0.2.0",
50
+ "pytest-asyncio>=1.2.0",
51
+ "pytest-xdist>=3.8.0",
52
+ ]
53
+ docs = [
54
+ "mkdocs>=1.6.0",
55
+ "mkdocs-material>=9.5.0",
56
+ "mkdocstrings[python]>=0.26.0",
57
+ "mkdocs-git-revision-date-localized-plugin>=1.2.0",
58
+ ]
59
+
60
+ [build-system]
61
+ requires = ["uv_build>=0.11.26,<0.12"]
62
+ build-backend = "uv_build"
63
+
64
+ [tool.uv]
65
+ # Single source of truth for the uv version: read locally by `uv` itself (errors on mismatch)
66
+ # and automatically by astral-sh/setup-uv in CI (falls back to pyproject.toml when no `version:`
67
+ # input is given). Bump with `uv run poe update-uv` — don't hand-edit.
68
+ required-version = "==0.11.26"
69
+
70
+ # TestPyPI staging index — release.yml publishes here (`uv publish --index testpypi`) before
71
+ # the real PyPI publish, as a dry run against the exact same Trusted Publishing mechanism.
72
+ [[tool.uv.index]]
73
+ name = "testpypi"
74
+ url = "https://test.pypi.org/simple/"
75
+ publish-url = "https://test.pypi.org/legacy/"
76
+ explicit = true
77
+
78
+ [tool.poe]
79
+ include = "tasks.toml"
@@ -0,0 +1,106 @@
1
+ """PyMediate - A type-safe mediator pattern implementation for Python.
2
+
3
+ PyMediate is a modern implementation of the Mediator Pattern that provides
4
+ type-safe request routing with automatic response type inference. It's designed
5
+ for Python 3.12+ and integrates seamlessly with dataclasses and dependency
6
+ injection frameworks.
7
+
8
+ Key Features:
9
+ - Type-safe: Full runtime validation with mypy support
10
+ - Zero convention: Uses type inspection instead of naming conventions
11
+ - Async/await support: Built-in async handlers and mediators via pymediate.aio
12
+ - DI ready: Built-in dependency-injector integration
13
+ - Dataclass friendly: Works seamlessly with @dataclass and Request[T]
14
+ - Well tested: 95%+ coverage enforced in CI
15
+
16
+ Quick Example:
17
+ ```python
18
+ from dataclasses import dataclass
19
+ from pymediate import Request, Handler, Mediator, Services
20
+
21
+ @dataclass
22
+ class UserCreated:
23
+ user_id: int
24
+ username: str
25
+
26
+ @dataclass
27
+ class CreateUser(Request[UserCreated]):
28
+ username: str
29
+ email: str
30
+
31
+ class CreateUserHandler(Handler[CreateUser]):
32
+ def __call__(self, req: CreateUser) -> UserCreated:
33
+ return UserCreated(user_id=1, username=req.username)
34
+
35
+ services = Services()
36
+ services.add(CreateUserHandler())
37
+ provider = services.provider()
38
+ mediator = Mediator(provider)
39
+
40
+ response = mediator.send(CreateUser(username="alice", email="alice@example.com"))
41
+ print(f"User {response.username} created with ID {response.user_id}")
42
+ ```
43
+
44
+ Main Components:
45
+ - Request: Base class for all requests
46
+ - Handler: Base class for synchronous handlers
47
+ - Mediator: Routes requests to handlers (sync version)
48
+ - ServiceProvider: Protocol for resolving service instances
49
+ - Services: Builder for registering services
50
+
51
+ Async Support:
52
+ For asynchronous operations, use the async variants from pymediate.aio:
53
+ ```python
54
+ from pymediate import Services
55
+ from pymediate.aio import Handler, Mediator
56
+
57
+ class AsyncHandler(Handler[CreateUser]):
58
+ async def __call__(self, req: CreateUser) -> UserCreated:
59
+ # Can use await here
60
+ result = await async_database_operation(req)
61
+ return UserCreated(user_id=result.id, username=req.username)
62
+
63
+ services = Services()
64
+ services.add(AsyncHandler())
65
+ provider = services.provider()
66
+ mediator = Mediator(provider)
67
+ response = await mediator.send(CreateUser(username="alice", email="alice@example.com"))
68
+ ```
69
+
70
+ For more information, see the documentation at https://sina-al.github.io/pymediate/
71
+ """
72
+
73
+ from .errors import (
74
+ HandlerAlreadyRegisteredError,
75
+ HandlerNotFoundError,
76
+ InvalidHandlerSignatureError,
77
+ InvalidRequestTypeError,
78
+ PyMediateError,
79
+ ResponseTypeMismatchError,
80
+ )
81
+ from .handler import Handler
82
+ from .mediator import Mediator
83
+ from .pipeline import PipelineBehavior
84
+ from .request import Request
85
+ from .service import ServiceNotFoundError, ServiceProvider, Services
86
+
87
+ __all__ = [
88
+ "Request",
89
+ "Handler",
90
+ "Mediator",
91
+ # Service Provider
92
+ "ServiceProvider",
93
+ "Services",
94
+ "ServiceNotFoundError",
95
+ # Pipeline
96
+ "PipelineBehavior",
97
+ # Errors
98
+ "PyMediateError",
99
+ "HandlerNotFoundError",
100
+ "HandlerAlreadyRegisteredError",
101
+ "InvalidHandlerSignatureError",
102
+ "InvalidRequestTypeError",
103
+ "ResponseTypeMismatchError",
104
+ ]
105
+
106
+ __version__ = "0.1.0"
@@ -0,0 +1,10 @@
1
+ """Internal implementation details for PyMediate.
2
+
3
+ This package contains internal utilities, base classes, and registries that are
4
+ not part of the public API. Users should not import from this package directly.
5
+
6
+ Warning:
7
+ The contents of this package are internal implementation details and may
8
+ change without notice in any release. Only import from the main `pymediate`
9
+ package or `pymediate.aio` for public APIs.
10
+ """