Using Click Commands in Python

I have a python program and i want to run it using command:

myprogram --readpower=some argument

import click
import csv
import json
import sys

@click.group(invoke_without_command=True)   
@click.option('--version', is_flag=True, default=False, help='Prints out pyisg package version being used')
def cli(version):
    """
    This utility is used to convert a CSV file to JSON file
    """
    if version:
        print("This is version 1.0 software")
        sys.exit()

@cli.command()
@click.option('--readpower', type=str, default="",
              help='Path of the csv file which is to be read)')

def read_csv(readpower,readspike,readdip):
{
    if readpower: 
        print("reading power")
}

if __name__ == "__main__":
    cli()

The problem i am facing is that the command -

myprogram --readpower = some argument

does not work.
I have to write the command as :

myprogram read_csv --readpower = some argument

2 answers

  • answered 2018-04-17 07:44 Lukisn

    Click is actually doing what it is supposed to do. You created a group cli and added the single command read_csv. So click needs to know the command to know what to invoke because there could possibly be more and even nested commands. You could create a standalone click command read_csvand register it in your setup.py file like so:

    # app.py
    import click
    
    # as a standalone command
    @click.command()
    @click.option('--readpower', type=str, default="")
    def read_csv(readpower):
        click.echo("doing stuff...")
        if readpower:
            click.echo("reading {}...".format(readpower))
    
    @click.group()
    def cli():
        pass
    
    @cli.command()
    def do_stuff():
        click.echo("doing stuff...")
    
    # as a subcommand in a group
    @cli.command()
    @click.option('--readpower', type=str, default="")
    def read_csv(readpower):
        click.echo("doing something...")
        if readpower:
            click.echo("reading {}...".format(readpower))
    

    And the setup:

    # setup.py
    from setuptools import setup
    
    setup(
        name='app',
        version='0.1',
        py_modules=['app'],
        install_requires=['Click'],
        entry_points='''
            [console_scripts]
            read_csv=app:read_csv
            cli=app:cli
        ''',
    )
    

    So you can set multiple entry points to your application and mix multiple standalone commands with grouped (and even possibly nested) commands.

  • answered 2018-04-18 00:36 Stephen Rauch

    Just get rid of the group since you don't want it. Use a command directly like:

    Code:

    import click
    import sys
    
    @click.command()
    @click.option('--version', is_flag=True, default=False,
                  help='Prints out pyisg package version being used')
    @click.option('--readpower', type=str, default="",
                  help='Path of the csv file which is to be read)')
    def cli(version, readpower):
        """
        This utility is used to convert a CSV file to JSON file
        """
        if version:
            click.echo("This is version 1.0 software")
            sys.exit()
    
        if readpower != '':
            click.echo("reading power {}".format(readpower))
    

    Test Code:

    if __name__ == "__main__":
        cli('--readpower=3'.split())
        cli('--version'.split())