garf-executors 0.2.3__py3-none-any.whl → 1.1.3__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 (49) hide show
  1. garf/executors/__init__.py +25 -0
  2. garf/executors/api_executor.py +228 -0
  3. garf/executors/bq_executor.py +179 -0
  4. garf/executors/config.py +52 -0
  5. garf/executors/entrypoints/__init__.py +0 -0
  6. garf/executors/entrypoints/cli.py +164 -0
  7. {garf_executors → garf/executors}/entrypoints/grpc_server.py +22 -9
  8. garf/executors/entrypoints/server.py +174 -0
  9. garf/executors/entrypoints/tracer.py +82 -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 +128 -0
  15. garf/executors/garf_pb2.py +51 -0
  16. {garf_executors → garf/executors}/garf_pb2_grpc.py +45 -2
  17. garf/executors/query_processor.py +79 -0
  18. garf/executors/setup.py +58 -0
  19. garf/executors/sql_executor.py +144 -0
  20. garf/executors/telemetry.py +20 -0
  21. garf/executors/workflows/__init__.py +0 -0
  22. garf/executors/workflows/gcp_workflow.yaml +49 -0
  23. garf/executors/workflows/workflow.py +164 -0
  24. garf/executors/workflows/workflow_runner.py +172 -0
  25. garf_executors/__init__.py +9 -44
  26. garf_executors/api_executor.py +9 -121
  27. garf_executors/bq_executor.py +9 -161
  28. garf_executors/config.py +9 -37
  29. garf_executors/entrypoints/__init__.py +25 -0
  30. garf_executors/entrypoints/cli.py +9 -148
  31. garf_executors/entrypoints/grcp_server.py +25 -0
  32. garf_executors/entrypoints/server.py +9 -102
  33. garf_executors/entrypoints/tracer.py +8 -40
  34. garf_executors/entrypoints/utils.py +9 -124
  35. garf_executors/exceptions.py +11 -3
  36. garf_executors/execution_context.py +9 -100
  37. garf_executors/executor.py +9 -108
  38. garf_executors/fetchers.py +9 -63
  39. garf_executors/sql_executor.py +9 -125
  40. garf_executors/telemetry.py +10 -5
  41. garf_executors/workflow.py +8 -79
  42. {garf_executors-0.2.3.dist-info → garf_executors-1.1.3.dist-info}/METADATA +18 -5
  43. garf_executors-1.1.3.dist-info/RECORD +46 -0
  44. {garf_executors-0.2.3.dist-info → garf_executors-1.1.3.dist-info}/WHEEL +1 -1
  45. garf_executors-1.1.3.dist-info/entry_points.txt +2 -0
  46. {garf_executors-0.2.3.dist-info → garf_executors-1.1.3.dist-info}/top_level.txt +1 -0
  47. garf_executors/garf_pb2.py +0 -45
  48. garf_executors-0.2.3.dist-info/RECORD +0 -24
  49. garf_executors-0.2.3.dist-info/entry_points.txt +0 -2
@@ -11,86 +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
- from __future__ import annotations
15
14
 
16
- import os
17
- import pathlib
18
15
 
19
- import pydantic
20
- import smart_open
21
- import yaml
16
+ import warnings
22
17
 
23
- from garf_executors.execution_context import ExecutionContext
18
+ from garf.executors.workflow import *
24
19
 
25
-
26
- class QueryPath(pydantic.BaseModel):
27
- """Path file with query."""
28
-
29
- path: str
30
-
31
-
32
- class QueryDefinition(pydantic.BaseModel):
33
- """Definition of a query."""
34
-
35
- query: Query
36
-
37
-
38
- class Query(pydantic.BaseModel):
39
- """Query elements.
40
-
41
- Attributes:
42
- text: Query text.
43
- title: Name of the query.
44
- """
45
-
46
- text: str
47
- title: str
48
-
49
-
50
- class ExecutionStep(ExecutionContext):
51
- """Common context for executing one or more queries.
52
-
53
- Attributes:
54
- fetcher: Name of a fetcher to get data from API.
55
- alias: Optional alias to identify execution step.
56
- queries: Queries to run for a particular fetcher.
57
- context: Execution context for queries and fetcher.
58
- """
59
-
60
- fetcher: str | None = None
61
- alias: str | None = None
62
- queries: list[QueryPath | QueryDefinition] | None = None
63
-
64
- @property
65
- def context(self) -> ExecutionContext:
66
- return ExecutionContext(
67
- writer=self.writer,
68
- writer_parameters=self.writer_parameters,
69
- query_parameters=self.query_parameters,
70
- fetcher_parameters=self.fetcher_parameters,
71
- )
72
-
73
-
74
- class Workflow(pydantic.BaseModel):
75
- """Orchestrates execution of queries for multiple fetchers.
76
-
77
- Attributes:
78
- steps: Contains one or several fetcher executions.
79
- """
80
-
81
- steps: list[ExecutionStep]
82
-
83
- @classmethod
84
- def from_file(cls, path: str | pathlib.Path | os.PathLike[str]) -> Workflow:
85
- """Builds workflow from local or remote yaml file."""
86
- with smart_open.open(path, 'r', encoding='utf-8') as f:
87
- data = yaml.safe_load(f)
88
- return Workflow(steps=data.get('steps'))
89
-
90
- def save(self, path: str | pathlib.Path | os.PathLike[str]) -> str:
91
- """Saves workflow to local or remote yaml file."""
92
- with smart_open.open(path, 'w', encoding='utf-8') as f:
93
- yaml.dump(
94
- self.model_dump(exclude_none=True).get('steps'), f, encoding='utf-8'
95
- )
96
- return f'Workflow is saved to {str(path)}'
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.2.3
3
+ Version: 1.1.3
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,8 +17,8 @@ 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
@@ -36,8 +36,15 @@ Provides-Extra: gcp
36
36
  Requires-Dist: opentelemetry-exporter-gcp-trace; extra == "gcp"
37
37
  Provides-Extra: server
38
38
  Requires-Dist: fastapi[standard]; extra == "server"
39
+ Requires-Dist: pydantic-settings; extra == "server"
39
40
  Requires-Dist: opentelemetry-instrumentation-fastapi; extra == "server"
40
41
  Requires-Dist: typer; extra == "server"
42
+ Requires-Dist: grpcio-reflection; extra == "server"
43
+ Provides-Extra: tests
44
+ Requires-Dist: pytest; extra == "tests"
45
+ Requires-Dist: pytest-mock; extra == "tests"
46
+ Requires-Dist: pytest-xdist; extra == "tests"
47
+ Requires-Dist: pytest-grpc; extra == "tests"
41
48
  Provides-Extra: all
42
49
  Requires-Dist: garf-executors[bq,gcp,server,sql]; extra == "all"
43
50
 
@@ -68,8 +75,14 @@ garf <QUERIES> --source <API_SOURCE> \
68
75
  where
69
76
 
70
77
  * `<QUERIES>`- local or remote path(s) to files with queries.
71
- * `<API_SOURCE>`- type of API to use. Based on that the appropriate report fetcher will be initialized.
72
- * `<OUTPUT_TYPE>` - output supported by [`garf-io` library](../garf_io/README.md).
78
+ * `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/)
79
+ * `output` - output supported by [`garf-io` library](https://google.github.io/garf/usage/writers/).
73
80
 
74
81
  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*.
75
82
  > Concrete `--source` parameters are dependent on a particular report fetcher and should be looked up in a documentation for this fetcher.
83
+
84
+ ## Documentation
85
+
86
+ Explore full documentation working with `garf-executors`
87
+
88
+ * [Documentation](https://google.github.io/garf/usage/executors/)
@@ -0,0 +1,46 @@
1
+ garf/executors/__init__.py,sha256=BRk66duc0hxzgiE35Qx0dsvNX0_bliEv-vNJb8EiNg8,824
2
+ garf/executors/api_executor.py,sha256=yZE6buZ7f4K31FLII3kurwpVGhQeK7OP8opiEHK9ZPs,7145
3
+ garf/executors/bq_executor.py,sha256=pM5MKVVpWtCl-Av3xfFRcAfQhCouFoYvhViWyGWY_V4,5863
4
+ garf/executors/config.py,sha256=w5g9EYabPtK-6CPl3G87owUvBiqi0_r_aeAwISpK-zw,1720
5
+ garf/executors/exceptions.py,sha256=U_7Q2ZMOUf89gzZd2pw7y3g7i1NeByPPKfpZ3q7p3ZU,662
6
+ garf/executors/execution_context.py,sha256=us_S-x2jsJOBo4Vm78DhCgcgnu_HPc-f9-q_XI_eowU,3840
7
+ garf/executors/executor.py,sha256=SpPONsYHO49WbZ2HRjTKujrNH64BbrSfKcZSn4Dcd6o,3830
8
+ garf/executors/fetchers.py,sha256=JemMM4FU4-Cpp2SxmMBtLgHgGy2gDsQSuuAozTh7Yjw,4477
9
+ garf/executors/garf_pb2.py,sha256=OIKC7NGErbUckhB4pQ6HycB9My5X3FvaImARnvhPExM,3450
10
+ garf/executors/garf_pb2_grpc.py,sha256=repGTh-ZDnNyAxMcJxAf0cLfr_JjX2AzZkY6PfZy0xM,4957
11
+ garf/executors/query_processor.py,sha256=IM5qXBNYJSUlsY2djYx8WDeX367cMhI1ZrITT22TcvI,2932
12
+ garf/executors/setup.py,sha256=S8eLYrW6XvITuwS88JeTq9XTE1MhMTX5UymHGDs0Ybw,2037
13
+ garf/executors/sql_executor.py,sha256=cneniSHQJ0Mx5Xbp9ykspb2__D84Uk15o7CWhrLBG-o,4869
14
+ garf/executors/telemetry.py,sha256=wLWAdJZmGinffIMv5FZNKaAUusgACTvokwhMFz2UCQ0,747
15
+ garf/executors/entrypoints/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
+ garf/executors/entrypoints/cli.py,sha256=U8vd7Rak5Y5llfLZLtZ55LO6mduMw7xvIAVe5I43-SI,6016
17
+ garf/executors/entrypoints/grpc_server.py,sha256=O7hinPjlVurSJjzudDFvVjkxX7xJHRcwFk4K4aJK0uo,2783
18
+ garf/executors/entrypoints/server.py,sha256=rLnOgZqeWwZ9UsJZ8LXDvZ101JrUIwMTpDzC5t-6wsY,4988
19
+ garf/executors/entrypoints/tracer.py,sha256=Oug3tePD8Yg5x6r1KNDx8RL_yAML0egy1DEFDobW8Uk,2792
20
+ garf/executors/entrypoints/utils.py,sha256=5XiGR2IOxdzAOY0lEWUeUV7tIpKBGRnQaIwBYvzQB7c,4337
21
+ garf/executors/workflows/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
+ garf/executors/workflows/gcp_workflow.yaml,sha256=KKfyFaBihFiLrsNhZct0cccxMV8CnVJUsxBsXQ8VP-g,1743
23
+ garf/executors/workflows/workflow.py,sha256=mr5YktxH6oIMasnowMLbEm5RTUIsTqTOIpHNuKm0UGQ,4810
24
+ garf/executors/workflows/workflow_runner.py,sha256=bFdFh2gdenKEPWyAqd_znaMwr5w0efQd3qEnxEvjD-k,5789
25
+ garf_executors/__init__.py,sha256=5Ol67ktUcC0q5d5pGblYfdlAsraJC-Gcr2U0uCN6rSs,772
26
+ garf_executors/api_executor.py,sha256=lmrPn6aheryM2jLRL2enU8GuKVUod3kEVkMYgjXn5EM,785
27
+ garf_executors/bq_executor.py,sha256=wQ8pd4d6dMByHtYl_i-FbebPKO5WRcvC_y9asG8H3Zk,784
28
+ garf_executors/config.py,sha256=3MXFdB3HAAdiBM58GmFA6HM6LcaA28mskUd5XUvJ5QM,779
29
+ garf_executors/exceptions.py,sha256=iBnO93AZRlmy_lo67ufQ67kv2FpBemu9VgDbwZx5b_s,783
30
+ garf_executors/execution_context.py,sha256=l5l5q8gPFNppOJ8q8TZfaaIEXmashTDu4denoGwMkpU,790
31
+ garf_executors/executor.py,sha256=0OPHePl_UG5k5o8UDid0HPu5QBCHnKFKvKv7vyx0LwE,781
32
+ garf_executors/fetchers.py,sha256=ayRzEp2-JvRhdkEmec10IKwX5SF25t6o03H1b9t5K3U,781
33
+ garf_executors/sql_executor.py,sha256=qhk5nZEq2a8QBvriiMWCE18xTQ29CSBQ7YPZ4Mr5DNA,785
34
+ garf_executors/telemetry.py,sha256=ncQ39dAE1tG0xKcyPAgEW8__0MhCSiBphZhisXeWp9k,782
35
+ garf_executors/workflow.py,sha256=vsxfjJVePu1NtWnVhCitMP_IZ-fcc9_H4fZS818_b70,781
36
+ garf_executors/entrypoints/__init__.py,sha256=DNA_m3MeyN10t8iSvhWjdlksR1GgIr-Wmy4Yuba5S3M,808
37
+ garf_executors/entrypoints/cli.py,sha256=Jaq46VnzltGMqJq9U6_3E3e_sC21VOon52gPYIrI8nY,812
38
+ garf_executors/entrypoints/grcp_server.py,sha256=HiYsfk31OgkPA4jcED3htJGidkRZH5NQIpkncVMCStk,820
39
+ garf_executors/entrypoints/server.py,sha256=JZCklhqx74PIhc4GIoOr2nNZz9n7QCfIm_vGyd3Q3dQ,815
40
+ garf_executors/entrypoints/tracer.py,sha256=JlDSgeDP0Q5Lk_pZLASDXPgZCPaKkWqZgaWOQ7JB-Bs,815
41
+ garf_executors/entrypoints/utils.py,sha256=iF-LBfKjrAhEW6HShh69RCPWVPC4Rf8iV5JEYSMhsx0,814
42
+ garf_executors-1.1.3.dist-info/METADATA,sha256=oDascP95RXOmlqUu5HuZ4fBzakYgeekmEBlI7nmH9CA,3605
43
+ garf_executors-1.1.3.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
44
+ garf_executors-1.1.3.dist-info/entry_points.txt,sha256=0IBZun3_hC4HYU-1krlbjTArZym3phu4jxYXs809ilw,61
45
+ garf_executors-1.1.3.dist-info/top_level.txt,sha256=UaHdWdgQhbiHyRzpYC-vW3Q7pdgbxXvTTBvDA655Jq4,20
46
+ garf_executors-1.1.3.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ garf = garf.executors.entrypoints.cli:main
@@ -1,45 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- # Generated by the protocol buffer compiler. DO NOT EDIT!
3
- # NO CHECKED-IN PROTOBUF GENCODE
4
- # source: garf.proto
5
- # Protobuf Python Version: 6.31.1
6
- """Generated protocol buffer code."""
7
- from google.protobuf import descriptor as _descriptor
8
- from google.protobuf import descriptor_pool as _descriptor_pool
9
- from google.protobuf import runtime_version as _runtime_version
10
- from google.protobuf import symbol_database as _symbol_database
11
- from google.protobuf.internal import builder as _builder
12
- _runtime_version.ValidateProtobufRuntimeVersion(
13
- _runtime_version.Domain.PUBLIC,
14
- 6,
15
- 31,
16
- 1,
17
- '',
18
- 'garf.proto'
19
- )
20
- # @@protoc_insertion_point(imports)
21
-
22
- _sym_db = _symbol_database.Default()
23
-
24
-
25
- from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2
26
-
27
-
28
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\ngarf.proto\x12\x04garf\x1a\x1cgoogle/protobuf/struct.proto\"g\n\x0e\x45xecuteRequest\x12\x0e\n\x06source\x18\x01 \x01(\t\x12\r\n\x05title\x18\x02 \x01(\t\x12\r\n\x05query\x18\x03 \x01(\t\x12\'\n\x07\x63ontext\x18\x04 \x01(\x0b\x32\x16.garf.ExecutionContext\"\xbc\x01\n\x10\x45xecutionContext\x12/\n\x10query_parameters\x18\x01 \x01(\x0b\x32\x15.garf.QueryParameters\x12\x33\n\x12\x66\x65tcher_parameters\x18\x02 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x0e\n\x06writer\x18\x03 \x01(\t\x12\x32\n\x11writer_parameters\x18\x04 \x01(\x0b\x32\x17.google.protobuf.Struct\"d\n\x0fQueryParameters\x12&\n\x05macro\x18\x01 \x01(\x0b\x32\x17.google.protobuf.Struct\x12)\n\x08template\x18\x02 \x01(\x0b\x32\x17.google.protobuf.Struct\"\"\n\x0f\x45xecuteResponse\x12\x0f\n\x07results\x18\x01 \x03(\t2G\n\x0bGarfService\x12\x38\n\x07\x45xecute\x12\x14.garf.ExecuteRequest\x1a\x15.garf.ExecuteResponse\"\x00\x62\x06proto3')
29
-
30
- _globals = globals()
31
- _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
32
- _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'garf_pb2', _globals)
33
- if not _descriptor._USE_C_DESCRIPTORS:
34
- DESCRIPTOR._loaded_options = None
35
- _globals['_EXECUTEREQUEST']._serialized_start=50
36
- _globals['_EXECUTEREQUEST']._serialized_end=153
37
- _globals['_EXECUTIONCONTEXT']._serialized_start=156
38
- _globals['_EXECUTIONCONTEXT']._serialized_end=344
39
- _globals['_QUERYPARAMETERS']._serialized_start=346
40
- _globals['_QUERYPARAMETERS']._serialized_end=446
41
- _globals['_EXECUTERESPONSE']._serialized_start=448
42
- _globals['_EXECUTERESPONSE']._serialized_end=482
43
- _globals['_GARFSERVICE']._serialized_start=484
44
- _globals['_GARFSERVICE']._serialized_end=555
45
- # @@protoc_insertion_point(module_scope)
@@ -1,24 +0,0 @@
1
- garf_executors/__init__.py,sha256=wZdLw0WyAGEK1y0Fdagvdd5xOWNKaPvL95yuaYziIWE,1941
2
- garf_executors/api_executor.py,sha256=IKYI1TK2HI2njxw7_X9n78wAQ1briAXxbA15Ybmt6nA,4295
3
- garf_executors/bq_executor.py,sha256=HKFBg4PhIaKM_SvjQy-ZbP7AsrsAF1FIj_w9gRqdICA,5756
4
- garf_executors/config.py,sha256=rZTAuBEa-Loi3DSamXFTjFQXHdeYJv71WOEbLLeo3l4,1721
5
- garf_executors/exceptions.py,sha256=U_7Q2ZMOUf89gzZd2pw7y3g7i1NeByPPKfpZ3q7p3ZU,662
6
- garf_executors/execution_context.py,sha256=WhHoN60vyeBUJbdjtOEZC1vUEyLwnIzBHbhT8co3yhs,3850
7
- garf_executors/executor.py,sha256=tobjdlOaAsc-nKLFSW-3qib5-ca6aHs5iw3Gn0sD72Y,3762
8
- garf_executors/fetchers.py,sha256=0bYurZs5jzxfGP9BgDnifdM6yRFvyCtKO-i3hFb5T5A,2605
9
- garf_executors/garf_pb2.py,sha256=mYvBYcAnZtyDflXGN2GZLM2KM0Nv9hoJs55zfQU_l1o,2564
10
- garf_executors/garf_pb2_grpc.py,sha256=w8D_r3wpj1ZZstkIFogY679-lSCcL2iZQ4QLO8IfToY,3359
11
- garf_executors/sql_executor.py,sha256=80WiuNBBWQz1y19LmWrzSk6auFFqh6YHBPTkFAGIhMs,4681
12
- garf_executors/telemetry.py,sha256=P75klGEoYgJ_-pR-izUIQ7B88ufskQ4vmW1rETg63Nc,747
13
- garf_executors/workflow.py,sha256=9Hkv0NgNyV5_xkkCTS6nsDVqtCmHfbqLQvdaIzFBrLU,2614
14
- garf_executors/entrypoints/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
- garf_executors/entrypoints/cli.py,sha256=Kei2Tqdw1syPKhbeK5u-1G72hXgmo1arXmxio150jPE,6006
16
- garf_executors/entrypoints/grpc_server.py,sha256=zP9C-dStbElWkb0T_IcIAcBxmA9Wl4GTWytUcrC_7Xg,2296
17
- garf_executors/entrypoints/server.py,sha256=FbemRjrGDgpr51iAMXdvTXlP1OG7Rc5i5M55Prw0wXg,3473
18
- garf_executors/entrypoints/tracer.py,sha256=VylQMIXOsRLuT3UlFwjRy8GJiPUI6zohUXiGX_DcE4g,1912
19
- garf_executors/entrypoints/utils.py,sha256=5XiGR2IOxdzAOY0lEWUeUV7tIpKBGRnQaIwBYvzQB7c,4337
20
- garf_executors-0.2.3.dist-info/METADATA,sha256=96n_J13NrBFbfz2-fVYo0KlD5p9r7qO8AQ3R_K2V710,3055
21
- garf_executors-0.2.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
22
- garf_executors-0.2.3.dist-info/entry_points.txt,sha256=LskWNFIw8j0WJuI18-32OZrlASXAMg1XtrRYwsKBz2E,61
23
- garf_executors-0.2.3.dist-info/top_level.txt,sha256=sP4dCXOENPn1hDFAunjMV8Js4NND_KGeO_gQWuaT0EY,15
24
- garf_executors-0.2.3.dist-info/RECORD,,
@@ -1,2 +0,0 @@
1
- [console_scripts]
2
- garf = garf_executors.entrypoints.cli:main