garf-executors 0.1.4__py3-none-any.whl → 1.0.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. garf/executors/__init__.py +60 -0
  2. garf/executors/api_executor.py +143 -0
  3. garf/executors/bq_executor.py +177 -0
  4. garf/executors/config.py +52 -0
  5. garf/executors/entrypoints/__init__.py +0 -0
  6. garf/executors/entrypoints/cli.py +177 -0
  7. garf/executors/entrypoints/grpc_server.py +67 -0
  8. garf/executors/entrypoints/server.py +117 -0
  9. garf/executors/entrypoints/tracer.py +57 -0
  10. garf/executors/entrypoints/utils.py +140 -0
  11. garf/executors/exceptions.py +17 -0
  12. garf/executors/execution_context.py +117 -0
  13. garf/executors/executor.py +124 -0
  14. garf/executors/fetchers.py +78 -0
  15. garf/executors/garf_pb2.py +45 -0
  16. garf/executors/garf_pb2_grpc.py +97 -0
  17. garf/executors/query_processor.py +61 -0
  18. garf/executors/sql_executor.py +142 -0
  19. garf/executors/telemetry.py +20 -0
  20. garf/executors/workflow.py +109 -0
  21. garf_executors/__init__.py +9 -44
  22. garf_executors/api_executor.py +9 -99
  23. garf_executors/bq_executor.py +9 -144
  24. garf_executors/config.py +9 -35
  25. garf_executors/entrypoints/__init__.py +25 -0
  26. garf_executors/entrypoints/cli.py +9 -116
  27. garf_executors/entrypoints/grcp_server.py +25 -0
  28. garf_executors/entrypoints/server.py +9 -92
  29. garf_executors/entrypoints/tracer.py +9 -26
  30. garf_executors/entrypoints/utils.py +9 -124
  31. garf_executors/exceptions.py +11 -3
  32. garf_executors/execution_context.py +9 -67
  33. garf_executors/executor.py +9 -71
  34. garf_executors/fetchers.py +9 -59
  35. garf_executors/sql_executor.py +9 -107
  36. garf_executors/telemetry.py +10 -5
  37. garf_executors/workflow.py +25 -0
  38. {garf_executors-0.1.4.dist-info → garf_executors-1.0.2.dist-info}/METADATA +17 -7
  39. garf_executors-1.0.2.dist-info/RECORD +42 -0
  40. garf_executors-1.0.2.dist-info/entry_points.txt +2 -0
  41. {garf_executors-0.1.4.dist-info → garf_executors-1.0.2.dist-info}/top_level.txt +1 -0
  42. garf_executors-0.1.4.dist-info/RECORD +0 -20
  43. garf_executors-0.1.4.dist-info/entry_points.txt +0 -2
  44. {garf_executors-0.1.4.dist-info → garf_executors-1.0.2.dist-info}/WHEEL +0 -0
@@ -1,4 +1,4 @@
1
- # Copyright 2022 Google LLC
1
+ # Copyright 2026 Google LLC
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -11,130 +11,15 @@
11
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
- """Module for various helpers for executing Garf as CLI tool."""
15
14
 
16
- from __future__ import annotations
17
15
 
18
- import enum
19
- import logging
20
- import sys
21
- from collections.abc import Sequence
22
- from typing import Any
16
+ import warnings
23
17
 
24
- from rich import logging as rich_logging
18
+ from garf.executors.entrypoints.utils import *
25
19
 
26
-
27
- class ParamsParser:
28
- def __init__(self, identifiers: Sequence[str]) -> None:
29
- self.identifiers = identifiers
30
-
31
- def parse(self, params: Sequence) -> dict[str, dict | None]:
32
- return {
33
- identifier: self._parse_params(identifier, params)
34
- for identifier in self.identifiers
35
- }
36
-
37
- def _parse_params(self, identifier: str, params: Sequence[Any]) -> dict:
38
- parsed_params = {}
39
- if params:
40
- raw_params = [param.split('=', maxsplit=1) for param in params]
41
- for param in raw_params:
42
- param_pair = self._identify_param_pair(identifier, param)
43
- if param_pair:
44
- parsed_params.update(param_pair)
45
- return parsed_params
46
-
47
- def _identify_param_pair(
48
- self, identifier: str, param: Sequence[str]
49
- ) -> dict[str, Any] | None:
50
- key = param[0]
51
- if not identifier or identifier not in key:
52
- return None
53
- provided_identifier, *keys = key.split('.')
54
- if not keys:
55
- return None
56
- if len(keys) > 1:
57
- raise GarfParamsException(
58
- f'{key} is invalid format,'
59
- f'`--{identifier}.key=value` or `--{identifier}.key` '
60
- 'are the correct formats'
61
- )
62
- provided_identifier = provided_identifier.replace('--', '')
63
- if provided_identifier not in self.identifiers:
64
- supported_arguments = ', '.join(self.identifiers)
65
- raise GarfParamsException(
66
- f'CLI argument {provided_identifier} is not supported'
67
- f', supported arguments {supported_arguments}'
68
- )
69
- if provided_identifier != identifier:
70
- return None
71
- key = keys[0].replace('-', '_')
72
- if not key:
73
- raise GarfParamsException(
74
- f'{identifier} {key} is invalid,'
75
- f'`--{identifier}.key=value` or `--{identifier}.key` '
76
- 'are the correct formats'
77
- )
78
- if len(param) == 2:
79
- return {key: param[1]}
80
- if len(param) == 1:
81
- return {key: True}
82
- raise GarfParamsException(
83
- f'{identifier} {key} is invalid,'
84
- f'`--{identifier}.key=value` or `--{identifier}.key` '
85
- 'are the correct formats'
86
- )
87
-
88
-
89
- class GarfParamsException(Exception):
90
- """Defines exception for incorrect parameters."""
91
-
92
-
93
- class LoggerEnum(str, enum.Enum):
94
- local = 'local'
95
- rich = 'rich'
96
- gcloud = 'gcloud'
97
-
98
-
99
- def init_logging(
100
- loglevel: str = 'INFO',
101
- logger_type: str | LoggerEnum = 'local',
102
- name: str = __name__,
103
- ) -> logging.Logger:
104
- loglevel = getattr(logging, loglevel)
105
- if logger_type == 'rich':
106
- logging.basicConfig(
107
- format='%(message)s',
108
- level=loglevel,
109
- datefmt='%Y-%m-%d %H:%M:%S',
110
- handlers=[
111
- rich_logging.RichHandler(rich_tracebacks=True),
112
- ],
113
- )
114
- elif logger_type == 'gcloud':
115
- try:
116
- import google.cloud.logging as glogging
117
- except ImportError as e:
118
- raise ImportError(
119
- 'Please install garf-executors with Cloud logging support - '
120
- '`pip install garf-executors[bq]`'
121
- ) from e
122
-
123
- client = glogging.Client()
124
- handler = glogging.handlers.CloudLoggingHandler(client, name=name)
125
- handler.close()
126
- glogging.handlers.setup_logging(handler, log_level=loglevel)
127
- logging.basicConfig(
128
- level=loglevel,
129
- handlers=[handler],
130
- )
131
- else:
132
- logging.basicConfig(
133
- format='[%(asctime)s][%(name)s][%(levelname)s] %(message)s',
134
- stream=sys.stdout,
135
- level=loglevel,
136
- datefmt='%Y-%m-%d %H:%M:%S',
137
- )
138
- logging.getLogger('smart_open.smart_open_lib').setLevel(logging.WARNING)
139
- logging.getLogger('urllib3.connectionpool').setLevel(logging.WARNING)
140
- return logging.getLogger(name)
20
+ warnings.warn(
21
+ "The 'garf_executors.entrypoints' namespace is deprecated. "
22
+ "Please use 'garf.executors.entrypoints' instead.",
23
+ DeprecationWarning,
24
+ stacklevel=2,
25
+ )
@@ -1,4 +1,4 @@
1
- # Copyright 2025 Google LLC
1
+ # Copyright 2026 Google LLC
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -13,5 +13,13 @@
13
13
  # limitations under the License.
14
14
 
15
15
 
16
- class GarfExecutorError(Exception):
17
- """Base class for garf executor exceptions."""
16
+ import warnings
17
+
18
+ from garf.executors.exceptions import *
19
+
20
+ warnings.warn(
21
+ "The 'garf_executors' namespace is deprecated. "
22
+ "Please use 'garf.executors' instead.",
23
+ DeprecationWarning,
24
+ stacklevel=2,
25
+ )
@@ -1,4 +1,4 @@
1
- # Copyright 2025 Google LLC
1
+ # Copyright 2026 Google LLC
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -12,72 +12,14 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- # pylint: disable=C0330, g-bad-import-order, g-multiple-import
16
15
 
17
- """Captures parameters for fetching data from APIs."""
16
+ import warnings
18
17
 
19
- from __future__ import annotations
18
+ from garf.executors.execution_context import *
20
19
 
21
- import os
22
- import pathlib
23
-
24
- import pydantic
25
- import smart_open
26
- import yaml
27
- from garf_core import query_editor
28
- from garf_io import writer
29
- from garf_io.writers import abs_writer
30
-
31
-
32
- class ExecutionContext(pydantic.BaseModel):
33
- """Common context for executing one or more queries.
34
-
35
- Attributes:
36
- query_parameters: Parameters to dynamically change query text.
37
- fetcher_parameters: Parameters to specify fetching setup.
38
- writer: Type of writer to use.
39
- writer_parameters: Optional parameters to setup writer.
40
- """
41
-
42
- query_parameters: query_editor.GarfQueryParameters | None = pydantic.Field(
43
- default_factory=dict
44
- )
45
- fetcher_parameters: dict[str, str | bool | int | list[str | int]] | None = (
46
- pydantic.Field(default_factory=dict)
47
- )
48
- writer: str | None = None
49
- writer_parameters: dict[str, str] | None = pydantic.Field(
50
- default_factory=dict
51
- )
52
-
53
- def model_post_init(self, __context__) -> None:
54
- if self.fetcher_parameters is None:
55
- self.fetcher_parameters = {}
56
- if self.writer_parameters is None:
57
- self.writer_parameters = {}
58
- if not self.query_parameters:
59
- self.query_parameters = query_editor.GarfQueryParameters()
60
-
61
- @classmethod
62
- def from_file(
63
- cls, path: str | pathlib.Path | os.PathLike[str]
64
- ) -> ExecutionContext:
65
- """Builds context from local or remote yaml file."""
66
- with smart_open.open(path, 'r', encoding='utf-8') as f:
67
- data = yaml.safe_load(f)
68
- return ExecutionContext(**data)
69
-
70
- def save(self, path: str | pathlib.Path | os.PathLike[str]) -> str:
71
- """Saves context to local or remote yaml file."""
72
- with smart_open.open(path, 'w', encoding='utf-8') as f:
73
- yaml.dump(self.model_dump(), f, encoding='utf-8')
74
- return f'ExecutionContext is saved to {str(path)}'
75
-
76
- @property
77
- def writer_client(self) -> abs_writer.AbsWriter:
78
- writer_client = writer.create_writer(self.writer, **self.writer_parameters)
79
- if self.writer == 'bq':
80
- _ = writer_client.create_or_get_dataset()
81
- if self.writer == 'sheet':
82
- writer_client.init_client()
83
- return writer_client
20
+ warnings.warn(
21
+ "The 'garf_executors' namespace is deprecated. "
22
+ "Please use 'garf.executors' instead.",
23
+ DeprecationWarning,
24
+ stacklevel=2,
25
+ )
@@ -1,4 +1,4 @@
1
- # Copyright 2025 Google LLC
1
+ # Copyright 2026 Google LLC
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -12,76 +12,14 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- """Defines common functionality between executors."""
16
15
 
17
- import asyncio
16
+ import warnings
18
17
 
19
- from opentelemetry import trace
18
+ from garf.executors.executor import *
20
19
 
21
- from garf_executors import execution_context
22
- from garf_executors.telemetry import tracer
23
-
24
-
25
- class Executor:
26
- """Defines common functionality between executors."""
27
-
28
- @tracer.start_as_current_span('api.execute_batch')
29
- def execute_batch(
30
- self,
31
- batch: dict[str, str],
32
- context: execution_context.ExecutionContext,
33
- parallel_threshold: int = 10,
34
- ) -> list[str]:
35
- """Executes batch of queries for a common context.
36
-
37
- Args:
38
- batch: Mapping between query_title and its text.
39
- context: Execution context.
40
- parallel_threshold: Number of queries to execute in parallel.
41
-
42
- Returns:
43
- Results of execution.
44
- """
45
- span = trace.get_current_span()
46
- span.set_attribute('api.parallel_threshold', parallel_threshold)
47
- return asyncio.run(
48
- self._run(
49
- batch=batch, context=context, parallel_threshold=parallel_threshold
50
- )
51
- )
52
-
53
- async def aexecute(
54
- self,
55
- query: str,
56
- title: str,
57
- context: execution_context.ExecutionContext,
58
- ) -> str:
59
- """Performs query execution asynchronously.
60
-
61
- Args:
62
- query: Location of the query.
63
- title: Name of the query.
64
- context: Query execution context.
65
-
66
- Returns:
67
- Result of writing the report.
68
- """
69
- return await asyncio.to_thread(self.execute, query, title, context)
70
-
71
- async def _run(
72
- self,
73
- batch: dict[str, str],
74
- context: execution_context.ExecutionContext,
75
- parallel_threshold: int,
76
- ):
77
- semaphore = asyncio.Semaphore(value=parallel_threshold)
78
-
79
- async def run_with_semaphore(fn):
80
- async with semaphore:
81
- return await fn
82
-
83
- tasks = [
84
- self.aexecute(query=query, title=title, context=context)
85
- for title, query in batch.items()
86
- ]
87
- return await asyncio.gather(*(run_with_semaphore(task) for task in tasks))
20
+ warnings.warn(
21
+ "The 'garf_executors' namespace is deprecated. "
22
+ "Please use 'garf.executors' instead.",
23
+ DeprecationWarning,
24
+ stacklevel=2,
25
+ )
@@ -1,4 +1,4 @@
1
- # Copyright 2025 Google LLC
1
+ # Copyright 2026 Google LLC
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -12,64 +12,14 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- import inspect
16
- import sys
17
- from importlib.metadata import entry_points
18
15
 
19
- from garf_core import report_fetcher
20
- from opentelemetry import trace
16
+ import warnings
21
17
 
22
- from garf_executors.telemetry import tracer
18
+ from garf.executors.fetchers import *
23
19
 
24
-
25
- @tracer.start_as_current_span('find_fetchers')
26
- def find_fetchers() -> set[str]:
27
- """Identifiers all available report fetchers."""
28
- if entrypoints := _get_entrypoints('garf'):
29
- return {fetcher.name for fetcher in entrypoints}
30
- return set()
31
-
32
-
33
- @tracer.start_as_current_span('get_report_fetcher')
34
- def get_report_fetcher(source: str) -> type[report_fetcher.ApiReportFetcher]:
35
- """Loads report fetcher for a given source.
36
-
37
- Args:
38
- source: Alias for a source associated with a fetcher.
39
-
40
- Returns:
41
- Class for a found report fetcher.
42
-
43
- Raises:
44
- ApiReportFetcherError: When fetcher cannot be loaded.
45
- MissingApiReportFetcherError: When fetcher not found.
46
- """
47
- if source not in find_fetchers():
48
- raise report_fetcher.MissingApiReportFetcherError(source)
49
- for fetcher in _get_entrypoints('garf'):
50
- if fetcher.name == source:
51
- try:
52
- with tracer.start_as_current_span('load_fetcher_module') as span:
53
- fetcher_module = fetcher.load()
54
- span.set_attribute('loaded_module', fetcher_module.__name__)
55
- for name, obj in inspect.getmembers(fetcher_module):
56
- if inspect.isclass(obj) and issubclass(
57
- obj, report_fetcher.ApiReportFetcher
58
- ):
59
- return getattr(fetcher_module, name)
60
- except ModuleNotFoundError:
61
- continue
62
- raise report_fetcher.ApiReportFetcherError(
63
- f'No fetcher available for the source "{source}"'
64
- )
65
-
66
-
67
- def _get_entrypoints(group='garf'):
68
- if sys.version_info.major == 3 and sys.version_info.minor == 9:
69
- try:
70
- fetchers = entry_points()[group]
71
- except KeyError:
72
- fetchers = []
73
- else:
74
- fetchers = entry_points(group=group)
75
- return fetchers
20
+ warnings.warn(
21
+ "The 'garf_executors' namespace is deprecated. "
22
+ "Please use 'garf.executors' instead.",
23
+ DeprecationWarning,
24
+ stacklevel=2,
25
+ )
@@ -1,4 +1,4 @@
1
- # Copyright 2024 Google LLC
1
+ # Copyright 2026 Google LLC
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -11,113 +11,15 @@
11
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
- """Defines mechanism for executing queries via SqlAlchemy."""
15
14
 
16
- from __future__ import annotations
17
15
 
18
- try:
19
- import sqlalchemy
20
- except ImportError as e:
21
- raise ImportError(
22
- 'Please install garf-executors with sqlalchemy support '
23
- '- `pip install garf-executors[sqlalchemy]`'
24
- ) from e
16
+ import warnings
25
17
 
26
- import logging
27
- import re
18
+ from garf.executors.sql_executor import *
28
19
 
29
- import pandas as pd
30
- from garf_core import query_editor, report
31
- from opentelemetry import trace
32
-
33
- from garf_executors import exceptions, execution_context, executor
34
- from garf_executors.telemetry import tracer
35
-
36
- logger = logging.getLogger(__name__)
37
-
38
-
39
- class SqlAlchemyQueryExecutorError(exceptions.GarfExecutorError):
40
- """Error when SqlAlchemyQueryExecutor fails to run query."""
41
-
42
-
43
- class SqlAlchemyQueryExecutor(
44
- executor.Executor, query_editor.TemplateProcessorMixin
45
- ):
46
- """Handles query execution via SqlAlchemy.
47
-
48
- Attributes:
49
- engine: Initialized Engine object to operated on a given database.
50
- """
51
-
52
- def __init__(self, engine: sqlalchemy.engine.base.Engine) -> None:
53
- """Initializes executor with a given engine.
54
-
55
- Args:
56
- engine: Initialized Engine object to operated on a given database.
57
- """
58
- self.engine = engine
59
-
60
- @classmethod
61
- def from_connection_string(
62
- cls, connection_string: str
63
- ) -> SqlAlchemyQueryExecutor:
64
- """Creates executor from SqlAlchemy connection string.
65
-
66
- https://docs.sqlalchemy.org/en/20/core/engines.html
67
- """
68
- engine = sqlalchemy.create_engine(connection_string)
69
- return cls(engine)
70
-
71
- @tracer.start_as_current_span('sql.execute')
72
- def execute(
73
- self,
74
- query: str,
75
- title: str,
76
- context: execution_context.ExecutionContext = (
77
- execution_context.ExecutionContext()
78
- ),
79
- ) -> report.GarfReport:
80
- """Executes query in a given database via SqlAlchemy.
81
-
82
- Args:
83
- query: Location of the query.
84
- title: Name of the query.
85
- context: Query execution context.
86
-
87
- Returns:
88
- Report with data if query returns some data otherwise empty Report.
89
- """
90
- span = trace.get_current_span()
91
- logging.info('Executing script: %s', title)
92
- query_text = self.replace_params_template(query, context.query_parameters)
93
- with self.engine.begin() as conn:
94
- if re.findall(r'(create|update) ', query_text.lower()):
95
- conn.connection.executescript(query_text)
96
- results = report.GarfReport()
97
- else:
98
- temp_table_name = f'temp_{title}'.replace('.', '_')
99
- query_text = f'CREATE TABLE {temp_table_name} AS {query_text}'
100
- conn.connection.executescript(query_text)
101
- try:
102
- results = report.GarfReport.from_pandas(
103
- pd.read_sql(f'SELECT * FROM {temp_table_name}', conn)
104
- )
105
- finally:
106
- conn.connection.execute(f'DROP TABLE {temp_table_name}')
107
- if context.writer and results:
108
- writer_client = context.writer_client
109
- logger.debug(
110
- 'Start writing data for query %s via %s writer',
111
- title,
112
- type(writer_client),
113
- )
114
- writing_result = writer_client.write(results, title)
115
- logger.debug(
116
- 'Finish writing data for query %s via %s writer',
117
- title,
118
- type(writer_client),
119
- )
120
- logger.info('%s executed successfully', title)
121
- return writing_result
122
- span.set_attribute('execute.num_results', len(results))
123
- return results
20
+ warnings.warn(
21
+ "The 'garf_executors' namespace is deprecated. "
22
+ "Please use 'garf.executors' instead.",
23
+ DeprecationWarning,
24
+ stacklevel=2,
25
+ )
@@ -1,4 +1,4 @@
1
- # Copyright 2025 Google LLC
1
+ # Copyright 2026 Google LLC
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -12,9 +12,14 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- # pylint: disable=C0330, g-bad-import-order, g-multiple-import
16
- from opentelemetry import trace
17
15
 
18
- tracer = trace.get_tracer(
19
- instrumenting_module_name='garf_executors',
16
+ import warnings
17
+
18
+ from garf.executors.telemetry import *
19
+
20
+ warnings.warn(
21
+ "The 'garf_executors' namespace is deprecated. "
22
+ "Please use 'garf.executors' instead.",
23
+ DeprecationWarning,
24
+ stacklevel=2,
20
25
  )
@@ -0,0 +1,25 @@
1
+ # Copyright 2026 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ import warnings
17
+
18
+ from garf.executors.workflow import *
19
+
20
+ warnings.warn(
21
+ "The 'garf_executors' namespace is deprecated. "
22
+ "Please use 'garf.executors' instead.",
23
+ DeprecationWarning,
24
+ stacklevel=2,
25
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: garf-executors
3
- Version: 0.1.4
3
+ Version: 1.0.2
4
4
  Summary: Executes queries against API and writes data to local/remote storage.
5
5
  Author-email: "Google Inc. (gTech gPS CSE team)" <no-reply@google.com>, Andrei Markin <andrey.markin.ppc@gmail.com>
6
6
  License: Apache 2.0
@@ -17,25 +17,29 @@ Classifier: Operating System :: OS Independent
17
17
  Classifier: License :: OSI Approved :: Apache Software License
18
18
  Requires-Python: >=3.9
19
19
  Description-Content-Type: text/markdown
20
- Requires-Dist: garf-core
21
- Requires-Dist: garf-io
20
+ Requires-Dist: garf-core>=1.0.0
21
+ Requires-Dist: garf-io>=1.0.0
22
22
  Requires-Dist: pyyaml
23
23
  Requires-Dist: pydantic
24
24
  Requires-Dist: opentelemetry-api
25
25
  Requires-Dist: opentelemetry-sdk
26
+ Requires-Dist: opentelemetry-exporter-otlp
26
27
  Provides-Extra: bq
27
28
  Requires-Dist: garf-io[bq]; extra == "bq"
28
29
  Requires-Dist: pandas; extra == "bq"
29
30
  Requires-Dist: google-cloud-logging; extra == "bq"
31
+ Requires-Dist: smart_open[gcs]; extra == "bq"
30
32
  Provides-Extra: sql
31
33
  Requires-Dist: garf-io[sqlalchemy]; extra == "sql"
32
34
  Requires-Dist: pandas; extra == "sql"
35
+ Provides-Extra: gcp
36
+ Requires-Dist: opentelemetry-exporter-gcp-trace; extra == "gcp"
33
37
  Provides-Extra: server
34
38
  Requires-Dist: fastapi[standard]; extra == "server"
35
39
  Requires-Dist: opentelemetry-instrumentation-fastapi; extra == "server"
36
- Requires-Dist: opentelemetry-exporter-otlp; extra == "server"
40
+ Requires-Dist: typer; extra == "server"
37
41
  Provides-Extra: all
38
- Requires-Dist: garf-executors[bq,server,sql]; extra == "all"
42
+ Requires-Dist: garf-executors[bq,gcp,server,sql]; extra == "all"
39
43
 
40
44
  # `garf-executors` - One stop-shop for interacting with Reporting APIs.
41
45
 
@@ -64,8 +68,14 @@ garf <QUERIES> --source <API_SOURCE> \
64
68
  where
65
69
 
66
70
  * `<QUERIES>`- local or remote path(s) to files with queries.
67
- * `<API_SOURCE>`- type of API to use. Based on that the appropriate report fetcher will be initialized.
68
- * `<OUTPUT_TYPE>` - output supported by [`garf-io` library](../garf_io/README.md).
71
+ * `source`- type of API to use. Based on that the appropriate report fetcher will be initialized. Explore supported APIs [here](https://google.github.io/garf/fetchers/overview/)
72
+ * `output` - output supported by [`garf-io` library](https://google.github.io/garf/usage/writers/).
69
73
 
70
74
  If your report fetcher requires additional parameters you can pass them via key value pairs under `--source.` argument, i.e.`--source.regionCode='US'` - to get data only from *US*.
71
75
  > Concrete `--source` parameters are dependent on a particular report fetcher and should be looked up in a documentation for this fetcher.
76
+
77
+ ## Documentation
78
+
79
+ Explore full documentation working with `garf-executors`
80
+
81
+ * [Documentation](https://google.github.io/garf/usage/executors/)