keripy icon indicating copy to clipboard operation
keripy copied to clipboard

Feature request: ability to specify keystore parameters as environment variables

Open lenkan opened this issue 9 months ago • 3 comments

Feature request description/rationale

I would like to be able to call kli commands that require keystore parameters such as --name, --base and possibly --passcode without having to supply them on the command line.

Example use:

export KERIPY_KEYSTORE_NAME="my_keystore"
export KERIPY_KEYSTORE_BASE="some_prefix"

# Now I can call kli incept without having to supply --name and --base parameters because they are stored in my environment.
kli incept --alias test --transferable --icount 1 --isith 1 --ncount 1 --nsith 1

# I can do more commands here without having to specify the keystore parameters
kli contacts list

The environment variables can be stored in files that I can source or load whichever way I want. If I run kli in a docker container, I would set the environment variables as part of the docker runtime.

Implementation

Implementation would be rather straightforward I think. We can just add default variables to the arguments.

parser.add_argument('--name', '-n', help='keystore name and file location of KERI keystore', required=True, default=os.getenv("KERIPY_KEYSTORE_NAME"))
parser.add_argument('--base', '-b', help='additional optional prefix to file location of KERI keystore', required=False, default=os.getenv("KERIPY_KEYSTORE_BASE") or "")

If you accept this feature request, I can open up a PR. Let me know your opinion. Also, whether or not you think the passcode can be added to the environment as well? If you think it is unsafe, we can add call it KERIPY_UNSAFE_PASSCODE or something, or skip it.

lenkan avatar Mar 27 '25 11:03 lenkan

Looked at this during the dev call, looks like a good feature.

kentbull avatar Apr 01 '25 14:04 kentbull

If I do this, I would like to extract all the duplicated declarations of --name, --base and --passcode

Option 1

I could use https://docs.python.org/3/library/argparse.html#parents and then a common module to create the key store arguments parser:

# cli.common.habbing module
from argparse import ArgumentParser
from os import getenv

def createKeystoreArgsParser(required: bool = True):
    parser = ArgumentParser(add_help=False)

    parser.add_argument('--name', '-n',
                        help='keystore name and file location of KERI keystore',
                        required=required,
                        default=getenv("KLI_KEYSTORE_NAME", None))
    parser.add_argument('--base', '-b',
                        help='additional optional prefix to file location of KERI keystore',
                        required=False,
                        default=getenv("KLI_KEYSTORE_BASE", ""))
    parser.add_argument('--passcode', '-p',
                        help='21 character encryption passcode for keystore (is not saved)', 
                        dest="bran",
                        default=None)

    return parser

# cli.sample-command module
from cli.common.habbing import createKeystoreArgsParser
from argparse import ArgumentParser

parser = argparse.ArgumentParser(description='Do some magic with the keystore', parents=[createKeystoreArgsParser()])
parser.set_defaults(handler=handler)
parser.add_argument('--other', '-o', help='some useful option specific to this command')

Option 2

Use a function that adds arguments to an existing parser

# cli.common.habbing module
from argparse import ArgumentParser
from os import getenv

def addKeystoreArgs(parser: ArgumentParser, required: bool = True):
    parser.add_argument('--name', '-n',
                        help='keystore name and file location of KERI keystore',
                        required=required,
                        default=getenv("KLI_KEYSTORE_NAME", None))
    parser.add_argument('--base', '-b',
                        help='additional optional prefix to file location of KERI keystore',
                        required=False,
                        default=getenv("KLI_KEYSTORE_BASE", ""))
    parser.add_argument('--passcode', '-p',
                        help='21 character encryption passcode for keystore (is not saved)', 
                        dest="bran",
                        default=None)

    return parser

# cli.sample-command module
from cli.common.habbing import addKeystoreArgs
from argparse import ArgumentParser

parser = argparse.ArgumentParser(description='Do some magic with the keystore'])
parser.set_defaults(handler=handler)
addKeystoreArgs(parser)
parser.add_argument('--other', '-o', help='some useful option specific to this command')

Option 3

I could use a shared set_defaults functions. However, it seems like we use set_defaults to invoke the action for the command, so I am not sure about that.

Option 4

I simply add default to all commands.

Other options

lenkan avatar Apr 01 '25 15:04 lenkan

Option 1 seems like the best option since that integrates with how argparse works. It does seem very similar to the function in Option 2.

kentbull avatar Apr 01 '25 17:04 kentbull