-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature/mx-1708 convert sinks to connectors (#367)
### PR Context - sibling PR to #366 ### Added - add a sink registry with `register_sink` and `get_sink` functions - add a `MultiSink` implementation, akin to `mex.extractors.load` ### Changes - BREAKING: convert post_to_backend_api to BackendApiSink - BREAKING: convert write_ndjson to NdjsonSink --------- Signed-off-by: Nicolas Drebenstedt <[email protected]> Co-authored-by: rababerladuseladim <[email protected]>
- Loading branch information
1 parent
4f66746
commit f702a11
Showing
9 changed files
with
198 additions
and
61 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
from abc import abstractmethod | ||
from collections.abc import Iterable | ||
|
||
from mex.common.connector import BaseConnector | ||
from mex.common.models import AnyExtractedModel | ||
from mex.common.types import Identifier | ||
|
||
|
||
class BaseSink(BaseConnector): | ||
"""Base class to define the interface of sink instances.""" | ||
|
||
def __init__(self) -> None: | ||
"""Create a new sink.""" | ||
|
||
def close(self) -> None: | ||
"""Close the sink.""" | ||
|
||
@abstractmethod | ||
def load( | ||
self, models: Iterable[AnyExtractedModel] | ||
) -> Iterable[Identifier]: # pragma: no cover | ||
"""Iteratively load models to a destination and yield their identifiers.""" | ||
... |
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
from collections.abc import Generator, Iterable | ||
from itertools import tee | ||
from typing import Final | ||
|
||
from mex.common.models import AnyExtractedModel | ||
from mex.common.settings import BaseSettings | ||
from mex.common.sinks.backend_api import BackendApiSink | ||
from mex.common.sinks.base import BaseSink | ||
from mex.common.sinks.ndjson import NdjsonSink | ||
from mex.common.types import Identifier, Sink | ||
|
||
_SINK_REGISTRY: Final[dict[Sink, type["BaseSink"]]] = {} | ||
|
||
|
||
class _MultiSink(BaseSink): | ||
"""Sink to load models to multiple sinks simultaneously.""" | ||
|
||
# This class is private because it should only be acquired by calling `get_sink`. | ||
|
||
_sinks: list[BaseSink] = [] | ||
|
||
def __init__(self) -> None: | ||
"""Instantiate the multi sink singleton.""" | ||
settings = BaseSettings.get() | ||
for sink in settings.sink: | ||
if sink in _SINK_REGISTRY: | ||
sink_cls = _SINK_REGISTRY[sink] | ||
self._sinks.append(sink_cls.get()) | ||
else: | ||
msg = f"Sink function not implemented: {sink}" | ||
raise RuntimeError(msg) | ||
|
||
def close(self) -> None: | ||
"""Close all underlying sinks.""" | ||
for sink in self._sinks: | ||
sink.close() | ||
|
||
def load( | ||
self, | ||
models: Iterable[AnyExtractedModel], | ||
) -> Generator[Identifier, None, None]: | ||
"""Load models to multiple sinks simultaneously.""" | ||
for sink, model_gen in zip( | ||
self._sinks, tee(models, len(self._sinks)), strict=True | ||
): | ||
yield from sink.load(model_gen) | ||
|
||
|
||
def register_sink(key: Sink, sink_cls: type["BaseSink"]) -> None: | ||
"""Register an implementation of a sink function to a settings key. | ||
Args: | ||
key: Possible value of `BaseSettings.sink` | ||
sink_cls: Implementation of the abstract sink class | ||
Raises: | ||
RuntimeError: When the `key` is already registered | ||
""" | ||
if key in _SINK_REGISTRY: | ||
msg = f"Already registered sink function: {key}" | ||
raise RuntimeError(msg) | ||
_SINK_REGISTRY[key] = sink_cls | ||
|
||
|
||
def get_sink() -> "BaseSink": | ||
"""Get a sink function that serves all configured `sink` destinations. | ||
Raises: | ||
RuntimeError: When the configured sink is not registered | ||
Returns: | ||
A function that pours the models into all configured sinks | ||
""" | ||
return _MultiSink.get() | ||
|
||
|
||
# register the default providers shipped with mex-common | ||
register_sink(Sink.BACKEND, BackendApiSink) | ||
register_sink(Sink.NDJSON, NdjsonSink) |
This file contains 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
This file contains 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
This file contains 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