pyline core
Project description
PyLine Core
A lightweight Python framework for implementing the Command Query Responsibility Segregation (CQRS) pattern with pipeline orchestration capabilities.
Key Features
- CQRS Implementation: Strong separation between Commands (write) and Queries (read).
- Mediator Pattern: Decouple components with a centralized handler registration.
- Pipeline Orchestration: Execute sequences of steps with a shared context, robust output type mapping, and automatic parameter validation.
- Event-Driven Architecture: Powerful background
EventBuswith Publish/Subscribe, subclass event propagation, and graceful shutdown. - Type-Safe: Modern Python type hints with generic queries and
@overloadsupport for superior developer experience. - Micro-Framework: Ultra-lightweight with zero external dependencies in core.
Installation
pip install pyline-core
Quick Start
1. Define Components and Register Handlers
Use the @mediator.register decorator to map Commands and Queries to their respective Handlers. Define the expected return type for Queries by inheriting from Query[TResult].
from pyline import Command, Query, CommandHandler, QueryHandler, mediator
from dataclasses import dataclass
@dataclass
class CreateUserCommand(Command):
name: str
@mediator.register(CreateUserCommand)
class CreateUserCommandHandler(CommandHandler):
async def handle(self, command: CreateUserCommand) -> None:
print(f"Creating user: {command.name}")
@dataclass
class GetUserQuery(Query[dict]):
name: str
@mediator.register(GetUserQuery)
class GetUserQueryHandler(QueryHandler[GetUserQuery, dict]):
async def handle(self, query: GetUserQuery) -> dict:
return {"id": 1, "name": query.name}
2. Execute Messages
# Execution
async def main():
# mediator.send is fully type-safe and returns None for Commands
await mediator.send(CreateUserCommand(name="Alp"))
# mediator.send knows GetUserQuery returns a dict
user = await mediator.send(GetUserQuery(name="Alp"))
print(user)
Advanced: Pipeline Orchestration
Chain multiple commands and queries into a single workflow with shared context. Results from steps (dicts, dataclasses, objects with __dict__ or __slots__) are automatically mapped and merged back into the context:
from pyline.pipe import Pipe
pipe = Pipe(
name="Registration Flow",
context={"name": "John Doe"},
steps=[CreateUserCommand, GetUserQuery]
)
# Throws a descriptive PipelineError if required context parameters are missing
await pipe.run()
Event-Driven Architecture (Event Bus)
PyLine Core includes a lightweight EventBus supporting subclass propagation to decouple components and handle side-effects asynchronously:
from pyline import BaseEvent, EventHandler, EventBus
from dataclasses import dataclass
import asyncio
@dataclass(frozen=True, kw_only=True)
class UserCreatedEvent(BaseEvent):
user_id: int
name: str
# EmailNotificationHandler listens specifically to UserCreatedEvent
class EmailNotificationHandler(EventHandler[UserCreatedEvent]):
async def handle(self, event: UserCreatedEvent) -> None:
print(f"Sending welcome email to User {event.user_id} ({event.name})")
# GeneralLogger listens to all events inheriting from BaseEvent
class GeneralLogger(EventHandler[BaseEvent]):
async def handle(self, event: BaseEvent) -> None:
print(f"Logging event {event.event_id} of type {type(event).__name__}")
async def main():
bus = EventBus()
bus.subscribe(UserCreatedEvent, EmailNotificationHandler())
bus.subscribe(BaseEvent, GeneralLogger()) # Will also trigger for UserCreatedEvent!
# Publish event (runs in the background)
bus.publish(UserCreatedEvent(user_id=1, name="Alp"))
# Gracefully shut down and wait for all background tasks
await bus.shutdown()
if __name__ == "__main__":
asyncio.run(main())
Documentation
For detailed guides and full API reference, visit our documentation site (coming soon).
Contributing
Contributions are welcome! Please see CONTRIBUTING.md for local development setup and standards.
License
MIT. See LICENSE for details.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyline_core-3.1.0.tar.gz.
File metadata
- Download URL: pyline_core-3.1.0.tar.gz
- Upload date:
- Size: 13.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dc56c368726516198839cb1cc5c94bf5fef07a0aa3a70e3e38e6398c5aea2ee6
|
|
| MD5 |
5cd5c2f43bab925733f474492ff410a3
|
|
| BLAKE2b-256 |
d5bca842a66b9a6ebf0dd844d0ab2da1409a8ded75ddf45678abddaa0f3e2df8
|
File details
Details for the file pyline_core-3.1.0-py3-none-any.whl.
File metadata
- Download URL: pyline_core-3.1.0-py3-none-any.whl
- Upload date:
- Size: 10.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3643c179327678b328b9747c7b275baf36f72593ac65cf81f33384ceadcd4fd2
|
|
| MD5 |
5f7ee3f3ea1f0e69fb617f78dd980b3f
|
|
| BLAKE2b-256 |
c1cae6591248cb57eef225b1605ec42b1373a46a0dbcf495e351436eaf58d84b
|