# Decouple
## Say NO to monolithic architecture.
Decouple complex system to separated modules by mediator.
```shell script
pip install decouple
```
## Register event handler
![register event handler](https://raw.githubusercontent.com/andrey-avdeev/decouple/master/docs/img/01_register.png)
## Dispatch events
![dispatch events](https://raw.githubusercontent.com/andrey-avdeev/decouple/master/docs/img/02_handle.png)
## Example
### Simple usage
Code of example is [here](https://github.com/andrey-avdeev/decouple/tree/master/examples/simple)
1. Write ModuleA - publisher
```python
from dataclasses import dataclass
from decouple import Module, Event, Mediator
class ModuleA(Module):
def __init__(self, mediator: Mediator = Mediator()):
super().__init__(mediator)
def start(self):
self.pub(StartEvent(a=7))
@dataclass
class StartEvent(Event):
a: int = 0 # must be serializable
```
2. Write ModuleB - subscriber
```python
from decouple import Module
from examples.simple.module_a import StartEvent
class ModuleB(Module):
def __init__(self):
super().__init__()
self.sub(StartEvent, self.handle_a)
def handle_start(self, event: StartEvent):
print(f'field a:{event.a}')
```
3. Compose both modules to the whole
```python
from examples.simple.module_a import ModuleA
from examples.simple.module_b import ModuleB
module_a = ModuleA()
module_a.add(ModuleB())
module_a.start()
```
### Priorities
Manual control
```python
from decouple import Module
from examples.simple.module_a import StartEvent
class ModuleB(Module):
def __init__(self):
super().__init__()
# handler with higher priority will be triggered early
self.sub(StartEvent, self.handle_b, priority=0)
self.sub(StartEvent, self.handle_a, priority=100)
def handle_a(self, event: StartEvent):
# will be triggered first
print(f'field a:{event.a}')
def handle_b(self, event: StartEvent):
# will be triggered second
print(f'event.uuid:{event.uuid}, event.timestamp:{event.timestamp}')
```
Default priority depends on registration order
```python
from decouple import Module
from examples.simple.module_a import StartEvent
class ModuleB(Module):
def __init__(self):
super().__init__()
# priority of handlers call increased by 1 every registration for the same event
self.sub(StartEvent, self.handle_b) # priority=1
self.sub(StartEvent, self.handle_a) # priority=2
def handle_a(self, event: StartEvent):
# will be triggered second
print(f'field a:{event.a}')
def handle_b(self, event: StartEvent):
# will be triggered first
print(f'event.uuid:{event.uuid}, event.timestamp:{event.timestamp}')
```
# Feedback
I will be glad to read your feedback in issues and pull requests.
Raw data
{
"_id": null,
"home_page": "https://github.com/andrey-avdeev/decouple",
"name": "decouple",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": "",
"keywords": "decouple mediator decoupling",
"author": "Andrey Avdeev",
"author_email": "seorazer@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/6c/e3/f70681dd89a96a701f22055caedc79cf88cebdeac9df827a5720bca80278/decouple-0.0.7.tar.gz",
"platform": "",
"description": "# Decouple\n## Say NO to monolithic architecture.\nDecouple complex system to separated modules by mediator.\n\n```shell script\npip install decouple\n```\n\n## Register event handler\n![register event handler](https://raw.githubusercontent.com/andrey-avdeev/decouple/master/docs/img/01_register.png)\n\n## Dispatch events\n![dispatch events](https://raw.githubusercontent.com/andrey-avdeev/decouple/master/docs/img/02_handle.png)\n\n## Example\n### Simple usage\nCode of example is [here](https://github.com/andrey-avdeev/decouple/tree/master/examples/simple)\n\n1. Write ModuleA - publisher\n```python\nfrom dataclasses import dataclass\n\nfrom decouple import Module, Event, Mediator\n\n\nclass ModuleA(Module):\n def __init__(self, mediator: Mediator = Mediator()):\n super().__init__(mediator)\n\n def start(self):\n self.pub(StartEvent(a=7))\n\n\n@dataclass\nclass StartEvent(Event):\n a: int = 0 # must be serializable\n```\n\n2. Write ModuleB - subscriber\n```python\nfrom decouple import Module\nfrom examples.simple.module_a import StartEvent\n\n\nclass ModuleB(Module):\n def __init__(self):\n super().__init__()\n\n self.sub(StartEvent, self.handle_a)\n\n def handle_start(self, event: StartEvent):\n print(f'field a:{event.a}')\n\n```\n\n3. Compose both modules to the whole\n```python\nfrom examples.simple.module_a import ModuleA\nfrom examples.simple.module_b import ModuleB\n\n\nmodule_a = ModuleA()\nmodule_a.add(ModuleB())\n\nmodule_a.start()\n```\n\n### Priorities\nManual control\n```python\nfrom decouple import Module\nfrom examples.simple.module_a import StartEvent\n\n\nclass ModuleB(Module):\n def __init__(self):\n super().__init__()\n\n # handler with higher priority will be triggered early\n self.sub(StartEvent, self.handle_b, priority=0)\n self.sub(StartEvent, self.handle_a, priority=100)\n\n def handle_a(self, event: StartEvent):\n # will be triggered first\n print(f'field a:{event.a}')\n\n def handle_b(self, event: StartEvent):\n # will be triggered second\n print(f'event.uuid:{event.uuid}, event.timestamp:{event.timestamp}')\n```\nDefault priority depends on registration order\n```python\nfrom decouple import Module\nfrom examples.simple.module_a import StartEvent\n\n\nclass ModuleB(Module):\n def __init__(self):\n super().__init__()\n\n # priority of handlers call increased by 1 every registration for the same event\n self.sub(StartEvent, self.handle_b) # priority=1\n self.sub(StartEvent, self.handle_a) # priority=2\n\n def handle_a(self, event: StartEvent):\n # will be triggered second\n print(f'field a:{event.a}')\n\n def handle_b(self, event: StartEvent):\n # will be triggered first\n print(f'event.uuid:{event.uuid}, event.timestamp:{event.timestamp}')\n```\n\n# Feedback\nI will be glad to read your feedback in issues and pull requests.",
"bugtrack_url": null,
"license": "Apache 2.0",
"summary": "Decoupling logic",
"version": "0.0.7",
"project_urls": {
"Homepage": "https://github.com/andrey-avdeev/decouple"
},
"split_keywords": [
"decouple",
"mediator",
"decoupling"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "6ce3f70681dd89a96a701f22055caedc79cf88cebdeac9df827a5720bca80278",
"md5": "4ffeaebb883be335262292aece329c04",
"sha256": "c253c1cc62b76e9720a066f334552548c6de1884bc3bdf456ddb62d61b867b09"
},
"downloads": -1,
"filename": "decouple-0.0.7.tar.gz",
"has_sig": false,
"md5_digest": "4ffeaebb883be335262292aece329c04",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 3324,
"upload_time": "2019-12-25T15:01:39",
"upload_time_iso_8601": "2019-12-25T15:01:39.824240Z",
"url": "https://files.pythonhosted.org/packages/6c/e3/f70681dd89a96a701f22055caedc79cf88cebdeac9df827a5720bca80278/decouple-0.0.7.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2019-12-25 15:01:39",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "andrey-avdeev",
"github_project": "decouple",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "decouple"
}