Last active
October 7, 2019 17:07
-
-
Save surenkov/ed84f25d24e1b66bf316143aaed83568 to your computer and use it in GitHub Desktop.
Some minimal service abstraction
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from abc import ABC, abstractmethod | |
from functools import reduce | |
from typing import Tuple, TypeVar, Union, Iterable, Mapping | |
TInstance = TypeVar("TInstance") | |
class AbstractFactory(Iterable[TInstance], ABC): | |
pass | |
class AbstractService(ABC): | |
__slots__ = () | |
def __call__(self, **kwargs): | |
return self.apply(**kwargs) | |
@abstractmethod | |
def apply(self, **kwargs): | |
pass | |
def then(self, service: "AbstractService"): | |
return flow(self, service) | |
class ServiceFlow(AbstractService): | |
__slots__ = ("services",) | |
def __init__(self, services: Tuple[AbstractService] = ()): | |
self.services = services | |
def then(self, *services: AbstractService) -> "ServiceFlow": | |
return ServiceFlow(self.services + services) | |
def apply(self, **kwargs): | |
def chain_call(prev_result, service): | |
if not isinstance(prev_result, Mapping): | |
prev_result = dict() | |
return service(**dict(kwargs, **prev_result)) | |
return reduce(chain_call, self.services, dict()) | |
def flow(*services: Union[AbstractService, Iterable[AbstractService]]): | |
def flatten_flow(prev_flow: ServiceFlow, service): | |
return prev_flow.then(service if callable(service) else flow(*service)) | |
return reduce(flatten_flow, services, ServiceFlow()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment