Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions cognite/client/config.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import annotations

import getpass
import os
import pprint
import re
import warnings
Expand All @@ -19,7 +20,8 @@ class GlobalConfig:
by the CogniteClient constructor if no config is passed directly. Defaults to None.
disable_gzip (bool): Whether or not to disable gzipping of json bodies. Defaults to False.
disable_pypi_version_check (bool): Whether or not to check for newer SDK versions when instantiating a new client.
Defaults to False.
Defaults to False. You can also set the environment variable ``COGNITE_DISABLE_PYPI_VERSION_CHECK`` to a truthy
value (``1``, ``true``, ``yes``, ``on``, case-insensitive) to disable the check without changing this attribute.
status_forcelist (Set[int]): HTTP status codes to retry. Defaults to {429, 502, 503, 504}
max_retries (int): Max number of retries on a given http request. Defaults to 10.
max_retries_connect (int): Max number of retries on connection errors. Defaults to 3.
Expand Down Expand Up @@ -100,6 +102,17 @@ def apply_settings(self, settings: dict[str, Any] | str) -> None:
global_config = GlobalConfig()


def _env_truthy(name: str) -> bool:
val = os.environ.get(name)
if val is None:
return False
return val.strip().lower() in {"1", "true", "yes", "on"}
Comment on lines +105 to +109
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

This function is missing a docstring, which is required by the repository style guide (lines 94, 117). Additionally, the set of truthy strings is a magic value and should be defined as a constant with an UPPER_SNAKE_CASE name, as per the style guide (line 87).

Since a module-level constant cannot be added within the scope of this change, defining it inside the function is an acceptable alternative.

def _env_truthy(name: str) -> bool:
    """Check if an environment variable is set to a truthy value.

    Truthy values are "1", "true", "yes", "on" (case-insensitive).

    Args:
        name (str): The name of the environment variable.

    Returns:
        bool: True if the environment variable has a truthy value, False otherwise.
    """
    TRUTHY_STRINGS = frozenset({"1", "true", "yes", "on"})
    val = os.environ.get(name)
    if val is None:
        return False
    return val.strip().lower() in TRUTHY_STRINGS
References
  1. Functions require concise docstrings in google-style format, including Args and Returns sections for clarity. (link)
  2. Constants should be named using UPPER_SNAKE_CASE. (link)



def _pypi_version_check_disabled() -> bool:
return global_config.disable_pypi_version_check or _env_truthy("COGNITE_DISABLE_PYPI_VERSION_CHECK")
Comment on lines +112 to +113
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

This function is missing a docstring, which is required by the repository style guide (lines 94, 117).

def _pypi_version_check_disabled() -> bool:
    """Check if the PyPI version check is disabled.

    The check is disabled if either the global config flag is set or the
    corresponding environment variable is set to a truthy value.

    Returns:
        bool: True if the version check is disabled, False otherwise.
    """
    return global_config.disable_pypi_version_check or _env_truthy("COGNITE_DISABLE_PYPI_VERSION_CHECK")
References
  1. Functions require concise docstrings in google-style format, including Args and Returns sections for clarity. (link)



class ClientConfig:
"""Configuration object for the client

Expand Down Expand Up @@ -145,7 +158,7 @@ def __init__(
self.debug = True
self._validate_config()

if not global_config.disable_pypi_version_check:
if not _pypi_version_check_disabled():
from cognite.client.utils._version_checker import check_client_is_running_latest_version

check_client_is_running_latest_version()
Expand Down
3 changes: 2 additions & 1 deletion cognite/client/utils/_version_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ def run() -> None:
if version.parse(__version__) < newest_version:
warnings.warn(
f"You are using version={__version__!r} of the SDK, however version={newest_version.public!r} is "
"available. To suppress this warning, either upgrade or do the following:\n"
"available. To suppress this warning, upgrade the package, set the environment variable "
"COGNITE_DISABLE_PYPI_VERSION_CHECK to a truthy value (e.g. 1 or true), or do the following:\n"
">>> from cognite.client.config import global_config\n"
">>> global_config.disable_pypi_version_check = True",
stacklevel=3,
Expand Down
23 changes: 23 additions & 0 deletions tests/tests_unit/test_config.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from contextlib import nullcontext as does_not_raise
from unittest.mock import patch

import pytest

Expand Down Expand Up @@ -131,3 +132,25 @@ def test_extract_invalid_cdf_cluster(
def test_extract_invalid_url(self, client_config: ClientConfig) -> None:
client_config.base_url = "invalid"
assert client_config.cdf_cluster is None

@pytest.mark.parametrize("env_value", ("1", "true", "TRUE", "yes", "on"))
def test_pypi_version_check_skipped_when_env_set(self, monkeypatch, env_value: str) -> None:
monkeypatch.setattr(global_config, "disable_pypi_version_check", False)
monkeypatch.setenv("COGNITE_DISABLE_PYPI_VERSION_CHECK", env_value)
with patch("cognite.client.utils._version_checker.check_client_is_running_latest_version") as check_fn:
ClientConfig(client_name="t", project="p", credentials=Token("x"))
check_fn.assert_not_called()

def test_pypi_version_check_runs_when_env_unset(self, monkeypatch) -> None:
monkeypatch.setattr(global_config, "disable_pypi_version_check", False)
monkeypatch.delenv("COGNITE_DISABLE_PYPI_VERSION_CHECK", raising=False)
with patch("cognite.client.utils._version_checker.check_client_is_running_latest_version") as check_fn:
ClientConfig(client_name="t", project="p", credentials=Token("x"))
check_fn.assert_called_once()

def test_pypi_version_check_skipped_when_global_config_true_despite_env(self, monkeypatch) -> None:
monkeypatch.setattr(global_config, "disable_pypi_version_check", True)
monkeypatch.delenv("COGNITE_DISABLE_PYPI_VERSION_CHECK", raising=False)
with patch("cognite.client.utils._version_checker.check_client_is_running_latest_version") as check_fn:
ClientConfig(client_name="t", project="p", credentials=Token("x"))
check_fn.assert_not_called()
Loading