MeltanoLabs / tap-google-analytics

Singer.io Tap for extracting data from the Google Analytics Reporting API
Apache License 2.0
11 stars 20 forks source link

GA4 - "Plugin configuration is invalid" #144

Open jeffsdata opened 1 year ago

jeffsdata commented 1 year ago

I am getting an error when following these instructions: https://hub.meltano.com/extractors/tap-ga4#end_date-setting

I've configured the tap and when I test it or invoke it, it just says: Plugin configuration is invalid 'utf-8' codec can't decode byte 0x92 in position 89: invalid start byte

When I put $env:MELTANO_CLI_LOG_LEVEL="debug", I get a little more info - it looks like it's occurring when listing out the dimensions on the property:

image

Here's the stack trace provided: C:\Users\jeffc\.local\pipx\venvs\meltano\lib\site-packages\meltano\cli\__init__.py:105 in │ │ _run_cli │ │ │ │ 102 │ """ │ │ 103 │ try: │ │ 104 │ │ try: # noqa: WPS225, WPS505 │ │ ❱ 105 │ │ │ cli(obj={"project": None}) │ │ 106 │ │ except ProjectReadonly as err: │ │ 107 │ │ │ raise CliError( │ │ 108 │ │ │ │ f"The requested action could not be completed: {err}", │ │ │ │ C:\Users\jeffc\.local\pipx\venvs\meltano\lib\site-packages\click\core.py:1157 in __call__ │ │ │ │ 1154 │ │ │ 1155 │ def __call__(self, *args: t.Any, **kwargs: t.Any) -> t.Any: │ │ 1156 │ │ """Alias for :meth:main.""" │ │ ❱ 1157 │ │ return self.main(*args, **kwargs) │ │ 1158 │ │ 1159 │ │ 1160 class Command(BaseCommand): │ │ │ │ C:\Users\jeffc\.local\pipx\venvs\meltano\lib\site-packages\meltano\cli\cli.py:43 in main │ │ │ │ 40 │ │ │ args: Positional arguments for the Click group. │ │ 41 │ │ │ kwargs: Keyword arguments for the Click group. │ │ 42 │ │ """ │ │ ❱ 43 │ │ return super().main(*args, windows_expand_args=False, **kwargs) │ │ 44 │ │ 45 │ │ 46 @click.group( │ │ │ │ C:\Users\jeffc\.local\pipx\venvs\meltano\lib\site-packages\click\core.py:1078 in main │ │ │ │ 1075 │ │ try: │ │ 1076 │ │ │ try: │ │ 1077 │ │ │ │ with self.make_context(prog_name, args, **extra) as ctx: │ │ ❱ 1078 │ │ │ │ │ rv = self.invoke(ctx) │ │ 1079 │ │ │ │ │ if not standalone_mode: │ │ 1080 │ │ │ │ │ │ return rv │ │ 1081 │ │ │ │ │ # it's not safe toctx.exit(rv)here! │ │ │ │ C:\Users\jeffc\.local\pipx\venvs\meltano\lib\site-packages\meltano\cli\utils.py:612 in invoke │ │ │ │ 609 │ │ enact_environment_behavior(self.environment_behavior, ctx) │ │ 610 │ │ if ctx.obj.get("tracker"): │ │ 611 │ │ │ ctx.obj["tracker"].add_contexts(CliContext.from_click_context(ctx)) │ │ ❱ 612 │ │ super().invoke(ctx) │ │ 613 │ │ 614 │ │ 615 class InstrumentedDefaultGroup(InstrumentedGroupMixin, DefaultGroup): │ │ │ │ C:\Users\jeffc\.local\pipx\venvs\meltano\lib\site-packages\click\core.py:1688 in invoke │ │ │ │ 1685 │ │ │ │ super().invoke(ctx) │ │ 1686 │ │ │ │ sub_ctx = cmd.make_context(cmd_name, args, parent=ctx) │ │ 1687 │ │ │ │ with sub_ctx: │ │ ❱ 1688 │ │ │ │ │ return _process_result(sub_ctx.command.invoke(sub_ctx)) │ │ 1689 │ │ │ │ 1690 │ │ # In chain mode we create the contexts step by step, but after the │ │ 1691 │ │ # base command has been invoked. Because at that point we do not │ │ │ │ C:\Users\jeffc\.local\pipx\venvs\meltano\lib\site-packages\meltano\cli\utils.py:612 in invoke │ │ │ │ 609 │ │ enact_environment_behavior(self.environment_behavior, ctx) │ │ 610 │ │ if ctx.obj.get("tracker"): │ │ 611 │ │ │ ctx.obj["tracker"].add_contexts(CliContext.from_click_context(ctx)) │ │ ❱ 612 │ │ super().invoke(ctx) │ │ 613 │ │ 614 │ │ 615 class InstrumentedDefaultGroup(InstrumentedGroupMixin, DefaultGroup): │ │ │ │ C:\Users\jeffc\.local\pipx\venvs\meltano\lib\site-packages\click\core.py:1688 in invoke │ │ │ │ 1685 │ │ │ │ super().invoke(ctx) │ │ 1686 │ │ │ │ sub_ctx = cmd.make_context(cmd_name, args, parent=ctx) │ │ 1687 │ │ │ │ with sub_ctx: │ │ ❱ 1688 │ │ │ │ │ return _process_result(sub_ctx.command.invoke(sub_ctx)) │ │ 1689 │ │ │ │ 1690 │ │ # In chain mode we create the contexts step by step, but after the │ │ 1691 │ │ # base command has been invoked. Because at that point we do not │ │ │ │ C:\Users\jeffc\.local\pipx\venvs\meltano\lib\site-packages\meltano\cli\utils.py:661 in invoke │ │ │ │ 658 │ │ if ctx.obj.get("tracker"): │ │ 659 │ │ │ ctx.obj["tracker"].add_contexts(CliContext.from_click_context(ctx)) │ │ 660 │ │ │ ctx.obj["tracker"].track_command_event(CliEvent.started) │ │ ❱ 661 │ │ super().invoke(ctx) │ │ 662 │ │ │ │ C:\Users\jeffc\.local\pipx\venvs\meltano\lib\site-packages\click\core.py:1434 in invoke │ │ │ │ 1431 │ │ │ echo(style(message, fg="red"), err=True) │ │ 1432 │ │ │ │ 1433 │ │ if self.callback is not None: │ │ ❱ 1434 │ │ │ return ctx.invoke(self.callback, **ctx.params) │ │ 1435 │ │ │ 1436 │ def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: │ │ 1437 │ │ """Return a list of completions for the incomplete value. Looks │ │ │ │ C:\Users\jeffc\.local\pipx\venvs\meltano\lib\site-packages\click\core.py:783 in invoke │ │ │ │ 780 │ │ │ │ 781 │ │ with augment_usage_errors(__self): │ │ 782 │ │ │ with ctx: │ │ ❱ 783 │ │ │ │ return __callback(*args, **kwargs) │ │ 784 │ │ │ 785 │ def forward( │ │ 786 │ │ __self, __cmd: "Command", *args: t.Any, **kwargs: t.Any # noqa: B902 │ │ │ │ C:\Users\jeffc\.local\pipx\venvs\meltano\lib\site-packages\click\decorators.py:33 in new_func │ │ │ │ 30 │ """ │ │ 31 │ │ │ 32 │ def new_func(*args: "P.args", **kwargs: "P.kwargs") -> "R": │ │ ❱ 33 │ │ return f(get_current_context(), *args, **kwargs) │ │ 34 │ │ │ 35 │ return update_wrapper(new_func, f) │ │ 36 │ │ │ │ C:\Users\jeffc\.local\pipx\venvs\meltano\lib\site-packages\meltano\cli\config.py:393 in test │ │ │ │ 390 │ │ │ 391 │ if not is_valid: │ │ 392 │ │ tracker.track_command_event(CliEvent.failed) │ │ ❱ 393 │ │ raise CliError("\n".join(("Plugin configuration is invalid", detail))) │ │ 394 │ │ │ 395 │ click.secho("Plugin configuration is valid", fg="green") │ │ 396 │ tracker.track_command_event(CliEvent.completed)

jeffsdata commented 1 year ago

Tried in Ubuntu as well, and got a similar error.

image

... and with debugging set to true:

image

Error: `Deleted configuration at /home/redox/repos/cpt-datajobs/.meltano/run/tap-ga4/tap.5a6eec51-cbc2-4eea-a528-fd5902d9a33b.config.json 2023-07-16T04:35:10.530652Z [debug ] Need help fixing this problem? Visit http://melta.no/ for troubleshooting steps, or to join our friendly Slack community.

'ascii' codec can't decode byte 0xe2 in position 89: ordinal not in range(128) ╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮ │ /home/redox/.local/lib/python3.10/site-packages/meltano/cli/init.py:94 in _run_cli │ │ │ │ 91 │ """ │ │ 92 │ try: │ │ 93 │ │ try: # noqa: WPS225, WPS505 │ │ ❱ 94 │ │ │ cli(obj={"project": None}) │ │ 95 │ │ except ProjectReadonly as err: │ │ 96 │ │ │ raise CliError( │ │ 97 │ │ │ │ f"The requested action could not be completed: {err}" │ │ │ │ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │ │ │ cli_error = CliError("Need help fixing this problem? Visit http://melta.no/ for │ │ │ │ troubleshooting steps, or to\njoin our friendly Slack community.\n\n'ascii' │ │ │ │ codec can't decode byte 0xe2 in position 89: ordinal not in range(128)") │ │ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /home/redox/.local/lib/python3.10/site-packages/click/core.py:1130 in call │ │ │ │ 1127 │ │ │ 1128 │ def call(self, *args: t.Any, kwargs: t.Any) -> t.Any: │ │ 1129 │ │ """Alias for :meth:main.""" │ │ ❱ 1130 │ │ return self.main(*args, *kwargs) │ │ 1131 │ │ 1132 │ │ 1133 class Command(BaseCommand): │ │ │ │ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │ │ │ args = () │ │ │ │ kwargs = { │ │ │ │ │ 'obj': { │ │ │ │ │ │ 'project': <meltano.core.project.Project object at 0x7f0dc581ba60>, │ │ │ │ │ │ 'verbosity': 0, │ │ │ │ │ │ 'is_default_environment': True, │ │ │ │ │ │ 'tracker': <meltano.core.tracking.tracker.Tracker object at │ │ │ │ 0x7f0dc581b820>, │ │ │ │ │ │ 'settings': <meltano.core.plugin.settings_service.PluginSettingsService │ │ │ │ object at 0x7f0dc542d600>, │ │ │ │ │ │ 'session': <sqlalchemy.orm.session.Session object at 0x7f0dc542fb20>, │ │ │ │ │ │ 'invoker': <meltano.core.plugin_invoker.PluginInvoker object at │ │ │ │ 0x7f0dc83fd240> │ │ │ │ │ } │ │ │ │ } │ │ │ │ self = │ │ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /home/redox/.local/lib/python3.10/site-packages/meltano/cli/cli.py:38 in main │ │ │ │ 35 │ │ │ args: Positional arguments for the Click group. │ │ 36 │ │ │ kwargs: Keyword arguments for the Click group. │ │ 37 │ │ """ │ │ ❱ 38 │ │ return super().main(args, windows_expand_args=False, kwargs) │ │ 39 │ │ 40 │ │ 41 @click.group( │ │ │ │ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │ │ │ class = <class 'meltano.cli.cli.NoWindowsGlobbingGroup'> │ │ │ │ args = () │ │ │ │ kwargs = { │ │ │ │ │ 'obj': { │ │ │ │ │ │ 'project': <meltano.core.project.Project object at 0x7f0dc581ba60>, │ │ │ │ │ │ 'verbosity': 0, │ │ │ │ │ │ 'is_default_environment': True, │ │ │ │ │ │ 'tracker': <meltano.core.tracking.tracker.Tracker object at │ │ │ │ 0x7f0dc581b820>, │ │ │ │ │ │ 'settings': <meltano.core.plugin.settings_service.PluginSettingsService │ │ │ │ object at 0x7f0dc542d600>, │ │ │ │ │ │ 'session': <sqlalchemy.orm.session.Session object at 0x7f0dc542fb20>, │ │ │ │ │ │ 'invoker': <meltano.core.plugin_invoker.PluginInvoker object at │ │ │ │ 0x7f0dc83fd240> │ │ │ │ │ } │ │ │ │ } │ │ │ │ self = │ │ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /home/redox/.local/lib/python3.10/site-packages/click/core.py:1055 in main │ │ │ │ 1052 │ │ try: │ │ 1053 │ │ │ try: │ │ 1054 │ │ │ │ with self.make_context(prog_name, args, **extra) as ctx: │ │ ❱ 1055 │ │ │ │ │ rv = self.invoke(ctx) │ │ 1056 │ │ │ │ │ if not standalone_mode: │ │ 1057 │ │ │ │ │ │ return rv │ │ 1058 │ │ │ │ │ # it's not safe to ctx.exit(rv) here! │ │ │ │ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │ │ │ args = ['config', 'tap-ga4', 'test'] │ │ │ │ complete_var = None │ │ │ │ ctx = <click.core.Context object at 0x7f0dc6cc3e50> │ │ │ │ extra = { │ │ │ │ │ 'obj': { │ │ │ │ │ │ 'project': <meltano.core.project.Project object at │ │ │ │ 0x7f0dc581ba60>, │ │ │ │ │ │ 'verbosity': 0, │ │ │ │ │ │ 'is_default_environment': True, │ │ │ │ │ │ 'tracker': <meltano.core.tracking.tracker.Tracker object at │ │ │ │ 0x7f0dc581b820>, │ │ │ │ │ │ 'settings': │ │ │ │ <meltano.core.plugin.settings_service.PluginSettingsService object at │ │ │ │ 0x7f0dc542d600>, │ │ │ │ │ │ 'session': <sqlalchemy.orm.session.Session object at │ │ │ │ 0x7f0dc542fb20>, │ │ │ │ │ │ 'invoker': <meltano.core.plugin_invoker.PluginInvoker object │ │ │ │ at 0x7f0dc83fd240> │ │ │ │ │ } │ │ │ │ } │ │ │ │ prog_name = 'meltano' │ │ │ │ self = │ │ │ │ standalone_mode = True │ │ │ │ windows_expand_args = False │ │ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /home/redox/.local/lib/python3.10/site-packages/meltano/cli/utils.py:541 in invoke │ │ │ │ 538 │ │ ctx.ensure_object(dict) │ │ 539 │ │ if ctx.obj.get("tracker"): │ │ 540 │ │ │ ctx.obj["tracker"].add_contexts(CliContext.from_click_context(ctx)) │ │ ❱ 541 │ │ super().invoke(ctx) # noqa: WPS608 │ │ 542 │ │ 543 │ │ 544 class InstrumentedCmd(click.Command): │ │ │ │ ╭───────────────────────── locals ──────────────────────────╮ │ │ │ class = <class 'meltano.cli.utils.InstrumentedGroup'> │ │ │ │ ctx = <click.core.Context object at 0x7f0dc6cc3e50> │ │ │ │ self = │ │ │ ╰───────────────────────────────────────────────────────────╯ │ │ │ │ /home/redox/.local/lib/python3.10/site-packages/click/core.py:1657 in invoke │ │ │ │ 1654 │ │ │ │ super().invoke(ctx) │ │ 1655 │ │ │ │ sub_ctx = cmd.make_context(cmd_name, args, parent=ctx) │ │ 1656 │ │ │ │ with sub_ctx: │ │ ❱ 1657 │ │ │ │ │ return _process_result(sub_ctx.command.invoke(sub_ctx)) │ │ 1658 │ │ │ │ 1659 │ │ # In chain mode we create the contexts step by step, but after the │ │ 1660 │ │ # base command has been invoked. Because at that point we do not │ │ │ │ ╭────────────────────────────────────────── locals ───────────────────────────────────────────╮ │ │ │ class = <class 'click.core.MultiCommand'> │ │ │ │ _process_result = <function MultiCommand.invoke.._process_result at 0x7f0dc9d63d90> │ │ │ │ args = ['tap-ga4', 'test'] │ │ │ │ cmd = │ │ │ │ cmd_name = 'config' │ │ │ │ ctx = <click.core.Context object at 0x7f0dc6cc3e50> │ │ │ │ self = │ │ │ │ sub_ctx = <click.core.Context object at 0x7f0dc9b2eec0> │ │ │ ╰─────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /home/redox/.local/lib/python3.10/site-packages/meltano/cli/utils.py:541 in invoke │ │ │ │ 538 │ │ ctx.ensure_object(dict) │ │ 539 │ │ if ctx.obj.get("tracker"): │ │ 540 │ │ │ ctx.obj["tracker"].add_contexts(CliContext.from_click_context(ctx)) │ │ ❱ 541 │ │ super().invoke(ctx) # noqa: WPS608 │ │ 542 │ │ 543 │ │ 544 class InstrumentedCmd(click.Command): │ │ │ │ ╭───────────────────────── locals ──────────────────────────╮ │ │ │ class = <class 'meltano.cli.utils.InstrumentedGroup'> │ │ │ │ ctx = <click.core.Context object at 0x7f0dc9b2eec0> │ │ │ │ self = │ │ │ ╰───────────────────────────────────────────────────────────╯ │ │ │ │ /home/redox/.local/lib/python3.10/site-packages/click/core.py:1657 in invoke │ │ │ │ 1654 │ │ │ │ super().invoke(ctx) │ │ 1655 │ │ │ │ sub_ctx = cmd.make_context(cmd_name, args, parent=ctx) │ │ 1656 │ │ │ │ with sub_ctx: │ │ ❱ 1657 │ │ │ │ │ return _process_result(sub_ctx.command.invoke(sub_ctx)) │ │ 1658 │ │ │ │ 1659 │ │ # In chain mode we create the contexts step by step, but after the │ │ 1660 │ │ # base command has been invoked. Because at that point we do not │ │ │ │ ╭────────────────────────────────────────── locals ───────────────────────────────────────────╮ │ │ │ class = <class 'click.core.MultiCommand'> │ │ │ │ _process_result = <function MultiCommand.invoke.._process_result at 0x7f0dc558c310> │ │ │ │ args = [] │ │ │ │ cmd = │ │ │ │ cmd_name = 'test' │ │ │ │ ctx = <click.core.Context object at 0x7f0dc9b2eec0> │ │ │ │ self = │ │ │ │ sub_ctx = <click.core.Context object at 0x7f0dc5853940> │ │ │ ╰─────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /home/redox/.local/lib/python3.10/site-packages/meltano/cli/utils.py:577 in invoke │ │ │ │ 574 │ │ if ctx.obj.get("tracker"): │ │ 575 │ │ │ ctx.obj["tracker"].add_contexts(CliContext.from_click_context(ctx)) │ │ 576 │ │ │ ctx.obj["tracker"].track_command_event(CliEvent.started) │ │ ❱ 577 │ │ super().invoke(ctx) # noqa: WPS608 │ │ 578 │ │ │ │ ╭──────────────────────────── locals ────────────────────────────╮ │ │ │ class = <class 'meltano.cli.utils.PartialInstrumentedCmd'> │ │ │ │ ctx = <click.core.Context object at 0x7f0dc5853940> │ │ │ │ self = │ │ │ ╰────────────────────────────────────────────────────────────────╯ │ │ │ │ /home/redox/.local/lib/python3.10/site-packages/click/core.py:1404 in invoke │ │ │ │ 1401 │ │ │ echo(style(message, fg="red"), err=True) │ │ 1402 │ │ │ │ 1403 │ │ if self.callback is not None: │ │ ❱ 1404 │ │ │ return ctx.invoke(self.callback, ctx.params) │ │ 1405 │ │ │ 1406 │ def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: │ │ 1407 │ │ """Return a list of completions for the incomplete value. Looks │ │ │ │ ╭─────────────────────── locals ───────────────────────╮ │ │ │ ctx = <click.core.Context object at 0x7f0dc5853940> │ │ │ │ self = │ │ │ ╰──────────────────────────────────────────────────────╯ │ │ │ │ /home/redox/.local/lib/python3.10/site-packages/click/core.py:760 in invoke │ │ │ │ 757 │ │ │ │ 758 │ │ with augment_usage_errors(self): │ │ 759 │ │ │ with ctx: │ │ ❱ 760 │ │ │ │ return callback(*args, *kwargs) │ │ 761 │ │ │ 762 │ def forward( │ │ 763 │ │ self, cmd: "Command", args: t.Any, kwargs: t.Any # noqa: B902 │ │ │ │ ╭────────────────────────────── locals ──────────────────────────────╮ │ │ │ _Context__callback = <function test at 0x7f0dc5a329e0> │ │ │ │ _Context__self = <click.core.Context object at 0x7f0dc5853940> │ │ │ │ args = () │ │ │ │ ctx = <click.core.Context object at 0x7f0dc5853940> │ │ │ │ kwargs = {} │ │ │ ╰────────────────────────────────────────────────────────────────────╯ │ │ │ │ /home/redox/.local/lib/python3.10/site-packages/click/decorators.py:26 in new_func │ │ │ │ 23 │ """ │ │ 24 │ │ │ 25 │ def new_func(*args, *kwargs): # type: ignore │ │ ❱ 26 │ │ return f(get_current_context(), args, **kwargs) │ │ 27 │ │ │ 28 │ return update_wrapper(t.cast(F, new_func), f) │ │ 29 │ │ │ │ ╭────────────────── locals ──────────────────╮ │ │ │ args = () │ │ │ │ f = <function test at 0x7f0dc5a324d0> │ │ │ │ kwargs = {} │ │ │ ╰────────────────────────────────────────────╯ │ │ │ │ /home/redox/.local/lib/python3.10/site-packages/meltano/cli/config.py:315 in test │ │ │ │ 312 │ │ │ return await plugin_test_service.validate() │ │ 313 │ │ │ 314 │ try: │ │ ❱ 315 │ │ is_valid, detail = asyncio.run(_validate()) │ │ 316 │ except Exception: │ │ 317 │ │ tracker.track_command_event(CliEvent.failed) │ │ 318 │ │ raise │ │ │ │ ╭───────────────────────────────────── locals ─────────────────────────────────────╮ │ │ │ _validate = <function test.._validate at 0x7f0dc54083a0> │ │ │ │ ctx = <click.core.Context object at 0x7f0dc5853940> │ │ │ │ invoker = <meltano.core.plugin_invoker.PluginInvoker object at 0x7f0dc83fd240> │ │ │ │ session = <sqlalchemy.orm.session.Session object at 0x7f0dc542fb20> │ │ │ │ tracker = <meltano.core.tracking.tracker.Tracker object at 0x7f0dc581b820> │ │ │ ╰──────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /usr/lib/python3.10/asyncio/runners.py:44 in run │ │ │ │ 41 │ │ events.set_event_loop(loop) │ │ 42 │ │ if debug is not None: │ │ 43 │ │ │ loop.set_debug(debug) │ │ ❱ 44 │ │ return loop.run_until_complete(main) │ │ 45 │ finally: │ │ 46 │ │ try: │ │ 47 │ │ │ _cancel_all_tasks(loop) │ │ │ │ ╭──────────────────────────────── locals ────────────────────────────────╮ │ │ │ debug = None │ │ │ │ loop = <_UnixSelectorEventLoop running=False closed=True debug=False> │ │ │ │ main = <coroutine object test.._validate at 0x7f0dc5169850> │ │ │ ╰────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /usr/lib/python3.10/asyncio/base_events.py:646 in run_until_complete │ │ │ │ 643 │ │ if not future.done(): │ │ 644 │ │ │ raise RuntimeError('Event loop stopped before Future completed.') │ │ 645 │ │ │ │ ❱ 646 │ │ return future.result() │ │ 647 │ │ │ 648 │ def stop(self): │ │ 649 │ │ """Stop running the event loop. │ │ │ │ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │ │ │ future = <Task finished name='Task-1' coro=<test.._validate() done, defined at │ │ │ │ /home/redox/.local/lib/python3.10/site-packages/meltano/cli/config.py:309> │ │ │ │ exception=UnicodeDecodeError('ascii', b' description: "Returns \\'true\\' if │ │ │ │ the link lead to a site is not a part of the property\xe2\x80\x99s domain. │ │ │ │ Automatically populated if Enhanced Measurement is enabled. Populated by the │ │ │ │ event parameter \\'outbound\\'."\n', 89, 90, 'ordinal not in range(128)')> │ │ │ │ new_task = True │ │ │ │ self = <_UnixSelectorEventLoop running=False closed=True debug=False> │ │ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /home/redox/.local/lib/python3.10/site-packages/meltano/cli/config.py:312 in _validate │ │ │ │ 309 │ async def _validate(): # noqa: WPS430 │ │ 310 │ │ plugin_test_service = PluginTestServiceFactory(invoker).get_test_service() │ │ 311 │ │ async with plugin_test_service.plugin_invoker.prepared(session): │ │ ❱ 312 │ │ │ return await plugin_test_service.validate() │ │ 313 │ │ │ 314 │ try: │ │ 315 │ │ is_valid, detail = asyncio.run(_validate()) │ │ │ │ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │ │ │ invoker = <meltano.core.plugin_invoker.PluginInvoker object at 0x7f0dc83fd240> │ │ │ │ plugin_test_service = <meltano.core.plugin_test_service.ExtractorTestService object at │ │ │ │ 0x7f0dc5219ea0> │ │ │ │ session = <sqlalchemy.orm.session.Session object at 0x7f0dc542fb20> │ │ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /home/redox/.local/lib/python3.10/site-packages/meltano/core/plugin_test_service.py:82 in │ │ validate │ │ │ │ 79 │ │ last_line = None │ │ 80 │ │ while not process.stdout.at_eof(): │ │ 81 │ │ │ data = await process.stdout.readline() │ │ ❱ 82 │ │ │ line = data.decode("ascii").strip() │ │ 83 │ │ │ if line: │ │ 84 │ │ │ │ logger.debug(line) │ │ 85 │ │ │ │ last_line = line │ │ │ │ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │ │ │ data = b' description: "Returns \\'true\\' if the link lead to a site is not a part │ │ │ │ of the'+130 │ │ │ │ last_line = 'ui_name: "Outbound"' │ │ │ │ line = 'ui_name: "Outbound"' │ │ │ │ process = <Process 2591125> │ │ │ │ self = <meltano.core.plugin_test_service.ExtractorTestService object at 0x7f0dc5219ea0> │ │ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 89: ordinal not in range(128)

The above exception was the direct cause of the following exception:

╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮ │ /home/redox/.local/lib/python3.10/site-packages/meltano/cli/init.py:104 in _run_cli │ │ │ │ 101 │ │ except MeltanoError as err: │ │ 102 │ │ │ handle_meltano_error(err) │ │ 103 │ │ except Exception as err: │ │ ❱ 104 │ │ │ raise CliError(f"{troubleshooting_message}\n{err}") from err │ │ 105 │ except CliError as cli_error: │ │ 106 │ │ cli_error.print() │ │ 107 │ │ sys.exit(1) │ │ │ │ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │ │ │ cli_error = CliError("Need help fixing this problem? Visit http://melta.no/ for │ │ │ │ troubleshooting steps, or to\njoin our friendly Slack community.\n\n'ascii' │ │ │ │ codec can't decode byte 0xe2 in position 89: ordinal not in range(128)") │ │ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ CliError: Need help fixing this problem? Visit http://melta.no/ for troubleshooting steps, or to join our friendly Slack community.

'ascii' codec can't decode byte 0xe2 in position 89: ordinal not in range(128) `

pnadolny13 commented 1 year ago

@jeffsdata This sounds like it's probably an issue with your config/meltano rather than this tap. Can you share your meltano.yml with anything sensitive removed?

When I googled your error I found this stack overflow answer that seems relevant. https://stackoverflow.com/a/29419477

jeffsdata commented 1 year ago

Sure, here's the meltano.yml. I haven't done aything to customize this.

version: 1
default_environment: dev
project_id: 431fcfd0-fcbb-4c53-ab8d-96ac8af0d448
environments:
- name: dev
- name: staging
- name: prod
plugins:
  extractors:
  - name: tap-ga4
    variant: meltanolabs
    pip_url: git+https://github.com/MeltanoLabs/tap-google-analytics.git
    config:
      end_date: '2023-01-02'
      flattening_enabled: true
      flattening_max_depth: 2
      reports: ga4reports.json
      start_date: '2023-01-01'
  loaders:
  - name: target-jsonl
    variant: andyh1203
    pip_url: target-jsonl
jeffsdata commented 1 year ago

I brought the tap-google-analytics repo local and tested it, and that worked fine with my report json and key file. So... it just doesn't seem to be working when I run it with meltano CLI (either by testing it or trying to run it).

meltano config tap-ga4 test meltano run tap-ga4 target-jsonl

pnadolny13 commented 1 year ago

@jeffsdata is that file in the root of your project where that tap is expecting it? Did you check your quotes based on the stack overflow post I linked? That seems related to the error message you were getting. Are you still seeing the same error message? ~You might have more luck if you ask this question in the Meltano slack channel so others can weigh in.~ I saw that you did post it there https://meltano.slack.com/archives/C01TCRBBJD7/p1691277643447539

jeffsdata commented 1 year ago

Yep, the ga4reports file is at the root. I also tried it without that file at all (in which case it uses the default one and I get the same error). I didn't realize... for way too long... but the actual connector works fine, but just the test isn't working. So, not a big deal, haha.

And yeah, I also checked for the windows smart quotes as well... I looked for it and it doesn't exist in any of the files - the Google service account file or the report file.