diff --git a/CHANGELOG.md b/CHANGELOG.md index f41e530..a5647df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## 0.2.17dev +* [Feature] Show link to sign up to Ploomber Cloud when loading telemetry + ## 0.2.16 (2023-11-17) * [Feature] Allow setting API key via the `PLOOMBER_CLOUD_KEY` environment variable diff --git a/src/ploomber_core/telemetry/telemetry.py b/src/ploomber_core/telemetry/telemetry.py index d3fde65..dba793e 100644 --- a/src/ploomber_core/telemetry/telemetry.py +++ b/src/ploomber_core/telemetry/telemetry.py @@ -103,6 +103,7 @@ class Internal(Config): """ last_version_check: datetime.datetime = None + last_cloud_check: datetime.datetime = None uid: str first_time: bool = True @@ -307,6 +308,34 @@ def check_version(package_name, version): internal.last_version_check = now +def check_cloud(): + """Displays a message to ask the user to sign up for Ploomber Cloud""" + settings = UserSettings() + + if not settings.version_check_enabled: + return + + # this feature is not documented. we added it to prevent the doctests + # from failing + if "PLOOMBER_VERSION_CHECK_DISABLED" in os.environ: + return + + now = datetime.datetime.now() + + # Check if we already notified in the last 2 days + if internal.last_cloud_check and (now - internal.last_cloud_check).days < 2: + return + + click.secho( + "Deploy AI and data apps for free on Ploomber Cloud! " + "Sign up here: https://www.platform.ploomber.io/register", + fg="green", + ) + + # Update latest check date + internal.last_cloud_check = now + + def _get_telemetry_info(package_name, version): """ The function checks for the local config and uid files, returns the right @@ -318,6 +347,7 @@ def _get_telemetry_info(package_name, version): # Check latest version check_version(package_name, version) + check_cloud() if telemetry_enabled: # Check first time install diff --git a/tests/telemetry/test_telemetry.py b/tests/telemetry/test_telemetry.py index 2c3e4a9..1bb29bd 100644 --- a/tests/telemetry/test_telemetry.py +++ b/tests/telemetry/test_telemetry.py @@ -133,6 +133,7 @@ def test_internal_create_file(tmp_directory, monkeypatch): assert content == { "uid": "some-unique-uuid", "last_version_check": None, + "last_cloud_check": None, "first_time": True, } assert internal.uid == "some-unique-uuid" @@ -364,8 +365,13 @@ def test_conf_file_after_version_check(tmp_directory, monkeypatch): telemetry.check_version("ploomber", "0.14.0") with version_path.open("r") as file: conf = yaml.safe_load(file) - assert "uid" in conf.keys() - assert len(conf.keys()) == 3 + + assert set(conf.keys()) == { + "first_time", + "last_cloud_check", + "last_version_check", + "uid", + } def test_get_version_timeout(): @@ -377,7 +383,7 @@ def test_get_version_timeout(): assert total_runtime < datetime.timedelta(milliseconds=1500) -def write_to_conf_file(tmp_directory, monkeypatch, last_check): +def write_to_conf_file(tmp_directory, monkeypatch, last_check, last_cloud_check=None): stats = Path("stats") stats.mkdir() conf_path = stats / "config.yaml" @@ -386,6 +392,9 @@ def write_to_conf_file(tmp_directory, monkeypatch, last_check): conf_path.write_text("version_check_enabled: True\n") version_path.write_text(f"last_version_check: {last_check}\n") + if last_cloud_check: + version_path.write_text(f"last_cloud_check: {last_cloud_check}\n") + # force to reset data so we load from the data we just wrote monkeypatch.setattr(telemetry, "internal", telemetry.Internal()) @@ -1025,3 +1034,43 @@ def my_function(x, y, z): } assert my_function.__wrapped__._telemetry_error is None + + +@pytest.mark.parametrize( + "last_cloud_check", + [ + None, + "2022-01-20 10:51:41.082376", + ], + ids=[ + "first-time", + "not-first-time", + ], +) +def test_check_cloud(tmp_directory, monkeypatch, capsys, last_cloud_check): + write_to_conf_file( + tmp_directory=tmp_directory, + monkeypatch=monkeypatch, + last_check="2022-01-20 10:51:41.082376", + last_cloud_check=last_cloud_check, + ) + + now = datetime.datetime.now() + fake_datetime = Mock() + fake_datetime.now.return_value = now + + with monkeypatch.context() as m: + m.setattr(telemetry.datetime, "datetime", fake_datetime) + telemetry.check_cloud() + + config = yaml.safe_load(Path("stats", "uid.yaml").read_text()) + + captured = capsys.readouterr() + + expected = ( + "Deploy AI and data apps for free on Ploomber Cloud!" + " Sign up here: https://www.platform.ploomber.io/register" + ) + + assert expected in captured.out + assert config["last_cloud_check"] == now