Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(telemetry): Remove consent confirmation prompt for kedro-telemetry #744

Merged
merged 11 commits into from
Jul 5, 2024
48 changes: 10 additions & 38 deletions kedro-telemetry/kedro_telemetry/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
from pathlib import Path
from typing import Any

import click
import requests
import toml
import yaml
Expand Down Expand Up @@ -347,14 +346,17 @@ def _send_heap_event(


def _check_for_telemetry_consent(project_path: Path) -> bool:
"""
Use telemetry consent from ".telemetry" file if it exists and has a valid format.
Telemetry is considered as opt-in otherwise.
"""
telemetry_file_path = project_path / ".telemetry"
if not telemetry_file_path.exists():
return _confirm_consent(telemetry_file_path)
with open(telemetry_file_path, encoding="utf-8") as telemetry_file:
telemetry = yaml.safe_load(telemetry_file)
if _is_valid_syntax(telemetry):
return telemetry["consent"]
return _confirm_consent(telemetry_file_path)
if telemetry_file_path.exists():
with open(telemetry_file_path, encoding="utf-8") as telemetry_file:
telemetry = yaml.safe_load(telemetry_file)
if _is_valid_syntax(telemetry):
return telemetry["consent"]
return True


def _is_valid_syntax(telemetry: Any) -> bool:
Expand All @@ -363,35 +365,5 @@ def _is_valid_syntax(telemetry: Any) -> bool:
)


def _confirm_consent(telemetry_file_path: Path) -> bool:
try:
with telemetry_file_path.open("w") as telemetry_file:
confirm_msg = (
"As an open-source project, we collect usage analytics. \n"
"We cannot see nor store information contained in "
"a Kedro project. \nYou can find out more by reading our "
"privacy notice: \n"
"https://github.com/kedro-org/kedro-plugins/tree/main/kedro-telemetry#"
"privacy-notice \n"
"Do you opt into usage analytics? "
)
if click.confirm(confirm_msg):
yaml.dump({"consent": True}, telemetry_file)
click.secho("You have opted into product usage analytics.", fg="green")
return True
click.secho(
"You have opted out of product usage analytics, so none will be collected.",
fg="green",
)
yaml.dump({"consent": False}, telemetry_file)
return False
except Exception as exc:
logger.warning(
"Failed to confirm consent. No data was sent to Heap. Exception: %s",
exc,
)
return False


cli_hooks = KedroTelemetryCLIHooks()
project_hooks = KedroTelemetryProjectHooks()
45 changes: 3 additions & 42 deletions kedro-telemetry/tests/test_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
KedroTelemetryCLIHooks,
KedroTelemetryProjectHooks,
_check_for_telemetry_consent,
_confirm_consent,
_is_known_ci_env,
)

Expand Down Expand Up @@ -371,8 +370,6 @@ def test_check_for_telemetry_consent_given(self, mocker, fake_metadata):
with open(telemetry_file_path, "w", encoding="utf-8") as telemetry_file:
yaml.dump({"consent": True}, telemetry_file)

mock_create_file = mocker.patch("kedro_telemetry.plugin._confirm_consent")
mock_create_file.assert_not_called()
assert _check_for_telemetry_consent(fake_metadata.project_path)

def test_check_for_telemetry_consent_not_given(self, mocker, fake_metadata):
Expand All @@ -381,29 +378,16 @@ def test_check_for_telemetry_consent_not_given(self, mocker, fake_metadata):
with open(telemetry_file_path, "w", encoding="utf-8") as telemetry_file:
yaml.dump({"consent": False}, telemetry_file)

mock_create_file = mocker.patch("kedro_telemetry.plugin._confirm_consent")
mock_create_file.assert_not_called()
assert not _check_for_telemetry_consent(fake_metadata.project_path)

def test_check_for_telemetry_consent_empty_file(self, mocker, fake_metadata):
Path(fake_metadata.project_path, "conf").mkdir(parents=True)
telemetry_file_path = fake_metadata.project_path / ".telemetry"
mock_create_file = mocker.patch(
"kedro_telemetry.plugin._confirm_consent", return_value=True
)

assert _check_for_telemetry_consent(fake_metadata.project_path)
mock_create_file.assert_called_once_with(telemetry_file_path)

def test_check_for_telemetry_no_consent_empty_file(self, mocker, fake_metadata):
Path(fake_metadata.project_path, "conf").mkdir(parents=True)
telemetry_file_path = fake_metadata.project_path / ".telemetry"
mock_create_file = mocker.patch(
"kedro_telemetry.plugin._confirm_consent", return_value=False
)
with open(telemetry_file_path, "w", encoding="utf-8") as telemetry_file:
yaml.dump({}, telemetry_file)

assert not _check_for_telemetry_consent(fake_metadata.project_path)
mock_create_file.assert_called_once_with(telemetry_file_path)
assert _check_for_telemetry_consent(fake_metadata.project_path)

def test_check_for_telemetry_consent_file_no_consent_field(
self, mocker, fake_metadata
Expand All @@ -413,37 +397,14 @@ def test_check_for_telemetry_consent_file_no_consent_field(
with open(telemetry_file_path, "w", encoding="utf8") as telemetry_file:
yaml.dump({"nonsense": "bla"}, telemetry_file)

mock_create_file = mocker.patch(
"kedro_telemetry.plugin._confirm_consent", return_value=True
)

assert _check_for_telemetry_consent(fake_metadata.project_path)
mock_create_file.assert_called_once_with(telemetry_file_path)

def test_check_for_telemetry_consent_file_invalid_yaml(self, mocker, fake_metadata):
Path(fake_metadata.project_path, "conf").mkdir(parents=True)
telemetry_file_path = fake_metadata.project_path / ".telemetry"
telemetry_file_path.write_text("invalid_ yaml")

mock_create_file = mocker.patch(
"kedro_telemetry.plugin._confirm_consent", return_value=True
)

assert _check_for_telemetry_consent(fake_metadata.project_path)
mock_create_file.assert_called_once_with(telemetry_file_path)

def test_confirm_consent_yaml_dump_error(self, mocker, fake_metadata, caplog):
Path(fake_metadata.project_path, "conf").mkdir(parents=True)
telemetry_file_path = fake_metadata.project_path / ".telemetry"
mocker.patch("yaml.dump", side_efyfect=Exception)

assert not _confirm_consent(telemetry_file_path)

msg = (
"Failed to confirm consent. No data was sent to Heap. Exception: "
"pytest: reading from stdin while output is captured! Consider using `-s`."
)
assert msg in caplog.messages[-1]

@mark.parametrize(
"env_vars,result",
Expand Down