From 4fc36078a3620f920ebb2d5e5ead733cfac7b586 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 23 Oct 2024 11:44:36 -0500 Subject: [PATCH] Add ability to get keys from a safe password store I use password-store but this can be configured to use anything that can print a key or secret on stdout. --- src/chap/key.py | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/src/chap/key.py b/src/chap/key.py index 2ff98f6..edb8381 100644 --- a/src/chap/key.py +++ b/src/chap/key.py @@ -2,6 +2,8 @@ # # SPDX-License-Identifier: MIT +import json +import subprocess from typing import Protocol import functools @@ -31,14 +33,30 @@ class NoKeyAvailable(Exception): _key_path_base = platformdirs.user_config_path("chap") - -@functools.cache -def get_key(name: str, what: str = "openai api key") -> str: - key_path = _key_path_base / name - if not key_path.exists(): - raise NoKeyAvailable( - f"Place your {what} in {key_path} and run the program again" - ) - - with open(key_path, encoding="utf-8") as f: - return f.read().strip() +USE_PASSWORD_STORE = _key_path_base / "USE_PASSWORD_STORE" + +if USE_PASSWORD_STORE.exists(): + content = USE_PASSWORD_STORE.read_text(encoding="utf-8") + if content.strip(): + cfg = json.loads(content) + pass_command: list[str] = cfg.get("PASS_COMMAND", ["pass", "show"]) + pass_prefix: str = cfg.get("PASS_PREFIX", "chap/") + + @functools.cache + def get_key(name: str, what: str = "api key") -> str: + key_path = f"{pass_prefix}{name}" + command = pass_command + [key_path] + return subprocess.check_output(command, encoding="utf-8").split("\n")[0] + +else: + + @functools.cache + def get_key(name: str, what: str = "api key") -> str: + key_path = _key_path_base / name + if not key_path.exists(): + raise NoKeyAvailable( + f"Place your {what} in {key_path} and run the program again" + ) + + with open(key_path, encoding="utf-8") as f: + return f.read().strip()