Skip to content

Commit

Permalink
llm keys command, closes #174
Browse files Browse the repository at this point in the history
  • Loading branch information
simonw committed Aug 21, 2023
1 parent 85e1838 commit e959026
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 3 deletions.
14 changes: 12 additions & 2 deletions docs/help.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,18 @@ Options:
--help Show this message and exit.
Commands:
path Output the path to the keys.json file
set Save a key in the keys.json file
list* List names of all stored keys
path Output the path to the keys.json file
set Save a key in the keys.json file
```
#### llm keys list --help
```
Usage: llm keys list [OPTIONS]
List names of all stored keys
Options:
--help Show this message and exit.
```
#### llm keys path --help
```
Expand Down
8 changes: 8 additions & 0 deletions docs/setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,19 @@ Once stored, this key will be automatically used for subsequent calls to the API
```bash
llm "Five ludicrous names for a pet lobster"
```

You can list the names of keys that have been set using this command:

```bash
llm keys
```

Keys that are stored in this way live in a file called `keys.json`. This file is located at the path shown when you run the following command:

```bash
llm keys path
```

On macOS this will be `~/Library/Application Support/io.datasette.llm/keys.json`. On Linux it may be something like `~/.config/io.datasette.llm/keys.json`.

### Passing keys using the --key option
Expand Down
19 changes: 18 additions & 1 deletion llm/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,11 +293,28 @@ def load_conversation(conversation_id: Optional[str]) -> Optional[Conversation]:
return conversation


@cli.group()
@cli.group(
cls=DefaultGroup,
default="list",
default_if_no_args=True,
)
def keys():
"Manage stored API keys for different models"


@keys.command(name="list")
def keys_list():
"List names of all stored keys"
path = user_dir() / "keys.json"
if not path.exists():
click.echo("No keys found")
return
keys = json.loads(path.read_text())
for key in sorted(keys.keys()):
if key != "// Note":
click.echo(key)


@keys.command(name="path")
def keys_path_command():
"Output the path to the keys.json file"
Expand Down
12 changes: 12 additions & 0 deletions tests/test_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,18 @@ def test_keys_set(monkeypatch, tmpdir):
}


@pytest.mark.parametrize("args", (["keys", "list"], ["keys"]))
def test_keys_list(monkeypatch, tmpdir, args):
user_path = str(tmpdir / "user/keys")
monkeypatch.setenv("LLM_USER_PATH", user_path)
runner = CliRunner()
result = runner.invoke(cli, ["keys", "set", "openai"], input="foo")
assert result.exit_code == 0
result2 = runner.invoke(cli, args)
assert result2.exit_code == 0
assert result2.output.strip() == "openai"


def test_uses_correct_key(mocked_openai, monkeypatch, tmpdir):
user_dir = tmpdir / "user-dir"
pathlib.Path(user_dir).mkdir()
Expand Down

0 comments on commit e959026

Please sign in to comment.