Skip to content

Commit 1bf993b

Browse files
[executors] feat: add class method from_parameters to ApiQueryExecutor
* Simplify initialization of fetchers
1 parent 3544ed2 commit 1bf993b

File tree

3 files changed

+45
-25
lines changed

3 files changed

+45
-25
lines changed

libs/garf_executors/garf_executors/__init__.py

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,12 @@
1515

1616
from __future__ import annotations
1717

18-
from garf_executors import bq_executor, exceptions, sql_executor
18+
from garf_executors import bq_executor, fetchers, sql_executor
1919
from garf_executors.api_executor import ApiExecutionContext, ApiQueryExecutor
20-
from garf_executors.fetchers import FETCHERS
2120

2221

2322
def setup_executor(source: str, fetcher_parameters: dict[str, str]):
2423
"""Initializes executors based on a source and parameters."""
25-
if source not in ('bq', 'sqldb') and not (
26-
concrete_api_fetcher := FETCHERS.get(source)
27-
):
28-
raise exceptions.GarfExecutorError(f'Source {source} is not available.')
2924
if source == 'bq':
3025
query_executor = bq_executor.BigQueryExecutor(**fetcher_parameters)
3126
elif source == 'sqldb':
@@ -35,16 +30,16 @@ def setup_executor(source: str, fetcher_parameters: dict[str, str]):
3530
)
3631
)
3732
else:
33+
concrete_api_fetcher = fetchers.get_report_fetcher(source)
3834
query_executor = ApiQueryExecutor(
3935
concrete_api_fetcher(**fetcher_parameters)
4036
)
4137
return query_executor
4238

4339

4440
__all__ = [
45-
'FETCHERS',
4641
'ApiQueryExecutor',
4742
'ApiExecutionContext',
4843
]
4944

50-
__version__ = '0.0.7'
45+
__version__ = '0.0.8'

libs/garf_executors/garf_executors/api_executor.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
import logging
2424

2525
from garf_core import report_fetcher
26-
from garf_executors import exceptions, execution_context, executor
26+
from garf_executors import exceptions, execution_context, executor, fetchers
2727

2828
logger = logging.getLogger(__name__)
2929

@@ -49,6 +49,13 @@ def __init__(self, fetcher: report_fetcher.ApiReportFetcher) -> None:
4949
"""
5050
self.fetcher = fetcher
5151

52+
@classmethod
53+
def from_fetcher_alias(
54+
cls, source: str, fetcher_parameters: dict[str, str]
55+
) -> ApiQueryExecutor:
56+
concrete_api_fetcher = fetchers.get_report_fetcher(source)
57+
return ApiQueryExecutor(concrete_api_fetcher(**fetcher_parameters))
58+
5259
async def aexecute(
5360
self,
5461
query: str,

libs/garf_executors/garf_executors/fetchers.py

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,41 @@
1515
import inspect
1616
from importlib.metadata import entry_points
1717

18-
from garf_core import report_fetcher
18+
from garf_core import exceptions, report_fetcher
1919

2020

21-
def get_report_fetchers() -> dict[str, report_fetcher.ApiReportFetcher]:
21+
def find_fetchers() -> set[str]:
22+
"""Identifiers all available report fetchers."""
23+
return {fetcher.name for fetcher in entry_points(group='garf')}
24+
25+
26+
def get_report_fetcher(source: str) -> type[report_fetcher.ApiReportFetcher]:
27+
"""Loads report fetcher for a given source.
28+
29+
Args:
30+
source: Alias for a source associated with a fetcher.
31+
32+
Returns:
33+
Class for a found report fetcher.
34+
35+
Raises:
36+
ApiReportFetcherError: When fetcher cannot be loaded.
37+
MissingApiReportFetcherError: When fetcher not found.
38+
"""
39+
if source not in find_fetchers():
40+
raise report_fetcher.MissingApiReportFetcherError(source)
2241
fetchers = entry_points(group='garf')
23-
found_fetchers = {}
2442
for fetcher in fetchers:
25-
try:
26-
fetcher_module = fetcher.load()
27-
for name, obj in inspect.getmembers(fetcher_module):
28-
if inspect.isclass(obj) and issubclass(
29-
obj, report_fetcher.ApiReportFetcher
30-
):
31-
found_fetchers[fetcher.name] = getattr(fetcher_module, name)
32-
except ModuleNotFoundError:
33-
continue
34-
return found_fetchers
35-
36-
37-
FETCHERS = get_report_fetchers()
43+
if fetcher.name == source:
44+
try:
45+
fetcher_module = fetcher.load()
46+
for name, obj in inspect.getmembers(fetcher_module):
47+
if inspect.isclass(obj) and issubclass(
48+
obj, report_fetcher.ApiReportFetcher
49+
):
50+
return getattr(fetcher_module, name)
51+
except ModuleNotFoundError:
52+
continue
53+
raise exceptions.ApiReportFetcherError(
54+
f'No fetcher available for the source "{source}"'
55+
)

0 commit comments

Comments
 (0)