Skip to content

fix config path & format #32

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

Merged
merged 15 commits into from
Jul 20, 2022
52 changes: 29 additions & 23 deletions src/iterative_telemetry/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import sys
import uuid
from functools import lru_cache
from pathlib import Path
from threading import Thread
from typing import Any, Callable, Dict, Union

Expand Down Expand Up @@ -187,39 +188,44 @@ def _system_info():
raise NotImplementedError


def generate_id():
"""TODO: check environ for CI-based ID"""
return str(uuid.uuid4())


@lru_cache(None)
def _find_or_create_user_id():
"""
The user's ID is stored on a file under the global config directory.
The file should contain a JSON with a "user_id" key:
{"user_id": "16fd2706-8baf-433b-82eb-8c7fada847da"}
IDs are generated randomly with UUID.
The file should contain a single string:
16fd2706-8baf-433b-82eb-8c7fada847da
IDs are generated randomly with UUID4.
"""

config_dir = user_config_dir("telemetry", "iterative")
fname = os.path.join(config_dir, "user_id")
lockfile = os.path.join(config_dir, "user_id.lock")

# Since the `fname` and `lockfile` are under the global config,
# we need to make sure such directory exist already.
os.makedirs(config_dir, exist_ok=True)
# DVC backwards-compatibility
old = Path(user_config_dir(str(Path("dvc") / "user_id"), "iterative"))
# cross-product path
new = Path(user_config_dir(str(Path("iterative") / "telemetry"), False))
new.parent.mkdir(mode=0o755, parents=True, exist_ok=True)
lockfile = str(new.with_suffix(".lock"))

try:
with FileLock( # pylint: disable=abstract-class-instantiated
lockfile, timeout=5
):
try:
with open(fname, encoding="utf8") as fobj:
user_id = json.load(fobj)["user_id"]

except (FileNotFoundError, ValueError, KeyError):
user_id = str(uuid.uuid4())

with open(fname, "w", encoding="utf8") as fobj:
json.dump({"user_id": user_id}, fobj)

return user_id

uid = generate_id()
if new.exists():
uid = new.read_text(encoding="utf8").strip()
else:
if old.exists():
uid = json.load(old.open(encoding="utf8"))["user_id"]
new.write_text(uid, encoding="utf8")

# only for non-DVC packages,
# write legacy file in case legacy DVC is installed later
if not old.exists() and uid.lower() != "do-not-track":
old.write_text(f'{{"user_id": "{uid}"}}', encoding="utf8")

return uid
except Timeout:
logger.debug("Failed to acquire %s", lockfile)
return None