Python Click - how to have contextually/dynamic overloaded command options

77 views Asked by At

I have created a CLI for my stow package that uses the add-on click_option_group package to group together options for each of the storage implementation managers supported. It describes what options will/can be passed to that manager and the help page can be seen below.

BTW the managers are loaded dynamically from pkg_resources, so the option groups are built as the cli is imported: the code can be found here https://github.com/Kieran-Bacon/stow/blob/develop/stow/cli.py

This issue is that every option is selectable regardless of the manager that is selected. So specifying the -p flag will be passed to the command method under the keyword path as defined in the first option regardless of whether you select the s3 manager (intending for -p to become profile).

e.g stow -m s3 -p profileName get s3://my-bucket/my-cool-file.txt leads to path and not profile being set.

The ideal solution would be that none of the options are valid by default and that only when a manager -m is selected, would its options become valid and used to parse the input (though the help should display all options and groups of options as it does below). So it would be perfectly fine to have overlapping flag definitions as the flag's keyword will be chosen contextually/dynamically

How am I meant to achieve this with Click? Without splitting the command and then having to duplicate the following commands?

Usage: stow [OPTIONS] COMMAND [ARGS]...

  Stow anything anywhere.

  Python based utility for the management of local and remote artefacts
  (files/directories) through a standard, expansive interface.

  Examples:
      >>> stow get s3://my-bucket/my-cool-file.txt local-file.txt
      <stow.File: c:\Users\kieran\Projects\personal\stow\local-file.txt modified(2023-09-14 09:14:36+00:00) size(3645479 bytes)>       

Options:
  -m, --manager [auto|fs|k8s|s3]  Select the manager you are connecting to -
                                  by default the manager will be guessed from
                                  the protocol
  FS configuration:               Options for the FS manager
    -r, --root TEXT               The root/cwd location of the manager
  Kubernetes configuration:       Options for the Kubernetes manager
    -p, --path TEXT               The default path for the manager
    -k, --kube-config-path TEXT   Provide path to kube config to load for
                                  credentials
    -c, --context TEXT            Select the kubernetes context
  Amazon configuration:           Options for the Amazon manager
    -k, --access-key TEXT         AWS access key id
    -s, --secret-key TEXT         AWS secret access key
    -t, --token TEXT              AWS session token
    -r, --region-name TEXT        Region name
    -p, --profile TEXT            Select aws profile credentials
  --debug / --no-debug
  --help                          Show this message and exit.

Commands:
  cat     Concatinate file contents with stuff
  cp      Copy a source artefact into the destination
  digest  Get artefact checksum using digest algorithm
  exists  Check if artefact exists
  get     Get (fetch|pull) an artefact and write to local destination
  ls      List artefacts in a directory
  mkdir   Create a directory at the path specified
  mklink  Create a symbolic link between to an artefact
  mv      Move an artefact to the destination location
  put     Put (push) a local artefact to the destination
  rm      Remove artefact
  sync    Syncronise source directory with destination directory
  touch   Perform the linux command touch, create a file/update file...
0

There are 0 answers