garf-executors 0.1.7__tar.gz → 0.2.0__tar.gz

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 (28) hide show
  1. {garf_executors-0.1.7 → garf_executors-0.2.0}/PKG-INFO +1 -1
  2. {garf_executors-0.1.7 → garf_executors-0.2.0}/garf_executors/__init__.py +2 -2
  3. {garf_executors-0.1.7 → garf_executors-0.2.0}/garf_executors/api_executor.py +5 -1
  4. {garf_executors-0.1.7 → garf_executors-0.2.0}/garf_executors/entrypoints/cli.py +18 -25
  5. {garf_executors-0.1.7 → garf_executors-0.2.0}/garf_executors/executor.py +38 -1
  6. {garf_executors-0.1.7 → garf_executors-0.2.0}/garf_executors.egg-info/PKG-INFO +1 -1
  7. {garf_executors-0.1.7 → garf_executors-0.2.0}/README.md +0 -0
  8. {garf_executors-0.1.7 → garf_executors-0.2.0}/garf_executors/bq_executor.py +0 -0
  9. {garf_executors-0.1.7 → garf_executors-0.2.0}/garf_executors/config.py +0 -0
  10. {garf_executors-0.1.7 → garf_executors-0.2.0}/garf_executors/entrypoints/__init__.py +0 -0
  11. {garf_executors-0.1.7 → garf_executors-0.2.0}/garf_executors/entrypoints/grpc_server.py +0 -0
  12. {garf_executors-0.1.7 → garf_executors-0.2.0}/garf_executors/entrypoints/server.py +0 -0
  13. {garf_executors-0.1.7 → garf_executors-0.2.0}/garf_executors/entrypoints/tracer.py +0 -0
  14. {garf_executors-0.1.7 → garf_executors-0.2.0}/garf_executors/entrypoints/utils.py +0 -0
  15. {garf_executors-0.1.7 → garf_executors-0.2.0}/garf_executors/exceptions.py +0 -0
  16. {garf_executors-0.1.7 → garf_executors-0.2.0}/garf_executors/execution_context.py +0 -0
  17. {garf_executors-0.1.7 → garf_executors-0.2.0}/garf_executors/fetchers.py +0 -0
  18. {garf_executors-0.1.7 → garf_executors-0.2.0}/garf_executors/garf_pb2.py +0 -0
  19. {garf_executors-0.1.7 → garf_executors-0.2.0}/garf_executors/garf_pb2_grpc.py +0 -0
  20. {garf_executors-0.1.7 → garf_executors-0.2.0}/garf_executors/sql_executor.py +0 -0
  21. {garf_executors-0.1.7 → garf_executors-0.2.0}/garf_executors/telemetry.py +0 -0
  22. {garf_executors-0.1.7 → garf_executors-0.2.0}/garf_executors.egg-info/SOURCES.txt +0 -0
  23. {garf_executors-0.1.7 → garf_executors-0.2.0}/garf_executors.egg-info/dependency_links.txt +0 -0
  24. {garf_executors-0.1.7 → garf_executors-0.2.0}/garf_executors.egg-info/entry_points.txt +0 -0
  25. {garf_executors-0.1.7 → garf_executors-0.2.0}/garf_executors.egg-info/requires.txt +0 -0
  26. {garf_executors-0.1.7 → garf_executors-0.2.0}/garf_executors.egg-info/top_level.txt +0 -0
  27. {garf_executors-0.1.7 → garf_executors-0.2.0}/pyproject.toml +0 -0
  28. {garf_executors-0.1.7 → garf_executors-0.2.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: garf-executors
3
- Version: 0.1.7
3
+ Version: 0.2.0
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
@@ -43,7 +43,7 @@ def setup_executor(
43
43
  else:
44
44
  concrete_api_fetcher = fetchers.get_report_fetcher(source)
45
45
  query_executor = ApiQueryExecutor(
46
- concrete_api_fetcher(
46
+ fetcher=concrete_api_fetcher(
47
47
  **fetcher_parameters,
48
48
  enable_cache=enable_cache,
49
49
  cache_ttl_seconds=cache_ttl_seconds,
@@ -57,4 +57,4 @@ __all__ = [
57
57
  'ApiExecutionContext',
58
58
  ]
59
59
 
60
- __version__ = '0.1.7'
60
+ __version__ = '0.2.0'
@@ -51,6 +51,10 @@ class ApiQueryExecutor(executor.Executor):
51
51
  fetcher: Instantiated report fetcher.
52
52
  """
53
53
  self.fetcher = fetcher
54
+ super().__init__(
55
+ preprocessors=self.fetcher.preprocessors,
56
+ postprocessors=self.fetcher.postprocessors,
57
+ )
54
58
 
55
59
  @classmethod
56
60
  def from_fetcher_alias(
@@ -59,7 +63,7 @@ class ApiQueryExecutor(executor.Executor):
59
63
  if not fetcher_parameters:
60
64
  fetcher_parameters = {}
61
65
  concrete_api_fetcher = fetchers.get_report_fetcher(source)
62
- return ApiQueryExecutor(concrete_api_fetcher(**fetcher_parameters))
66
+ return ApiQueryExecutor(fetcher=concrete_api_fetcher(**fetcher_parameters))
63
67
 
64
68
  @tracer.start_as_current_span('api.execute')
65
69
  def execute(
@@ -88,14 +88,6 @@ def main():
88
88
  raise exceptions.GarfExecutorError(
89
89
  f'No execution context found for source {args.source} in {config_file}'
90
90
  )
91
- query_executor = garf_executors.setup_executor(
92
- source=args.source,
93
- fetcher_parameters=context.fetcher_parameters,
94
- enable_cache=args.enable_cache,
95
- cache_ttl_seconds=args.cache_ttl_seconds,
96
- )
97
- batch = {query: reader_client.read(query) for query in args.query}
98
- query_executor.execute_batch(batch, context, args.parallel_threshold)
99
91
  else:
100
92
  param_types = ['source', 'macro', 'template']
101
93
  outputs = args.output.split(',')
@@ -116,23 +108,24 @@ def main():
116
108
  writer_parameters=writer_parameters,
117
109
  fetcher_parameters=source_parameters,
118
110
  )
119
- query_executor = garf_executors.setup_executor(
120
- source=args.source,
121
- fetcher_parameters=context.fetcher_parameters,
122
- enable_cache=args.enable_cache,
123
- cache_ttl_seconds=args.cache_ttl_seconds,
124
- )
125
- if args.parallel_queries and len(args.query) > 1:
126
- logger.info('Running queries in parallel')
127
- batch = {query: reader_client.read(query) for query in args.query}
128
- query_executor.execute_batch(batch, context, args.parallel_threshold)
129
- else:
130
- if len(args.query) > 1:
131
- logger.info('Running queries sequentially')
132
- for query in args.query:
133
- query_executor.execute(
134
- query=reader_client.read(query), title=query, context=context
135
- )
111
+ query_executor = garf_executors.setup_executor(
112
+ source=args.source,
113
+ fetcher_parameters=context.fetcher_parameters,
114
+ enable_cache=args.enable_cache,
115
+ cache_ttl_seconds=args.cache_ttl_seconds,
116
+ )
117
+ batch = {query: reader_client.read(query) for query in args.query}
118
+ if args.parallel_queries and len(args.query) > 1:
119
+ logger.info('Running queries in parallel')
120
+ batch = {query: reader_client.read(query) for query in args.query}
121
+ query_executor.execute_batch(batch, context, args.parallel_threshold)
122
+ else:
123
+ if len(args.query) > 1:
124
+ logger.info('Running queries sequentially')
125
+ for query in args.query:
126
+ query_executor.execute(
127
+ query=reader_client.read(query), title=query, context=context
128
+ )
136
129
  logging.shutdown()
137
130
 
138
131
 
@@ -15,7 +15,10 @@
15
15
  """Defines common functionality between executors."""
16
16
 
17
17
  import asyncio
18
+ import inspect
19
+ from typing import Optional
18
20
 
21
+ from garf_core import report_fetcher
19
22
  from opentelemetry import trace
20
23
 
21
24
  from garf_executors import execution_context
@@ -25,6 +28,14 @@ from garf_executors.telemetry import tracer
25
28
  class Executor:
26
29
  """Defines common functionality between executors."""
27
30
 
31
+ def __init__(
32
+ self,
33
+ preprocessors: Optional[dict[str, report_fetcher.Processor]] = None,
34
+ postprocessors: Optional[dict[str, report_fetcher.Processor]] = None,
35
+ ) -> None:
36
+ self.preprocessors = preprocessors or {}
37
+ self.postprocessors = postprocessors or {}
38
+
28
39
  @tracer.start_as_current_span('api.execute_batch')
29
40
  def execute_batch(
30
41
  self,
@@ -34,6 +45,9 @@ class Executor:
34
45
  ) -> list[str]:
35
46
  """Executes batch of queries for a common context.
36
47
 
48
+ If an executor has any pre/post processors, executes them first while
49
+ modifying the context.
50
+
37
51
  Args:
38
52
  batch: Mapping between query_title and its text.
39
53
  context: Execution context.
@@ -44,11 +58,19 @@ class Executor:
44
58
  """
45
59
  span = trace.get_current_span()
46
60
  span.set_attribute('api.parallel_threshold', parallel_threshold)
47
- return asyncio.run(
61
+ _handle_processors(processors=self.preprocessors, context=context)
62
+ results = asyncio.run(
48
63
  self._run(
49
64
  batch=batch, context=context, parallel_threshold=parallel_threshold
50
65
  )
51
66
  )
67
+ _handle_processors(processors=self.postprocessors, context=context)
68
+ return results
69
+
70
+ def add_preprocessor(
71
+ self, preprocessors: dict[str, report_fetcher.Processor]
72
+ ) -> None:
73
+ self.preprocessors.update(preprocessors)
52
74
 
53
75
  async def aexecute(
54
76
  self,
@@ -85,3 +107,18 @@ class Executor:
85
107
  for title, query in batch.items()
86
108
  ]
87
109
  return await asyncio.gather(*(run_with_semaphore(task) for task in tasks))
110
+
111
+
112
+ def _handle_processors(
113
+ processors: dict[str, report_fetcher.Processor],
114
+ context: execution_context.ExecutionContext,
115
+ ) -> None:
116
+ for k, processor in processors.items():
117
+ processor_signature = list(inspect.signature(processor).parameters.keys())
118
+ if k in context.fetcher_parameters:
119
+ processor_parameters = {
120
+ k: v
121
+ for k, v in context.fetcher_parameters.items()
122
+ if k in processor_signature
123
+ }
124
+ context.fetcher_parameters[k] = processor(**processor_parameters)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: garf-executors
3
- Version: 0.1.7
3
+ Version: 0.2.0
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
File without changes
File without changes