Search code examples
pythoncommand-lineconsolesetuptoolspython-click

How to set entry point for console script with multiple command groups for Python Click?


Given that my library with foobar.py is setup as such:

\foobar.py
\foobar
    \__init__.py
\setup.py

Hierarchy of CLI in the console script:

foobar.py
    \cli
         \foo
             \kungfu
             \kungpow
         \bar
             \blacksheep
             \haveyouanywool

[code]:

import click

CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])


@click.group()
@click.version_option()
def cli():
    pass

@cli.group(context_settings=CONTEXT_SETTINGS)
def foo():
    pass

@cli.group(context_settings=CONTEXT_SETTINGS)
def bar():
    pass

@foo.command('kungfu')
def kungfu():
    print('bruise lee')

@foo.command('kungpow')
def kungpow():
    print('chosen one')

@bar.command('blacksheep')
def blacksheep():
    print('bah bah blacksheep')

@bar.command('haveyouanywool')
def haveyouanywool():
    print('have you any wool?')

How should I set my entry in setup.py?

There are many examples but they only show a single command for a single entry point, e.g. Entry Points in setup.py

But is it even possible to setup the console script with how the my foobar.py click script is structured?

If not, how should I restructure the commands in foobar.py?


For context, I have this script for the sacremoses library: https://github.com/alvations/sacremoses/blob/cli/sacremoses.py

But I couldn't figure how to configure the setup.py to install the sacremoses.py script properly: https://github.com/alvations/sacremoses/blob/cli/setup.py


Solution

  • To make the entry points work in your example you need:

    entry_points='''
        [console_scripts]
        command_line_name=foobar:cli
    ''',
    

    What you are missing is an understanding of the meaning of:

    command_line_name=foobar:cli
    

    [console_scripts]

    There are three things in command_line_name=foobar:cli:

    1. Name of the script from the command line (command_line_name)
    2. Module where the click command handler is located (foobar)
    3. Name of the click command/group in that module (cli)

    setup.py

    For your github example, I would suggest:

    from distutils.core import setup
    import setuptools
    
    console_scripts = """
    [console_scripts]
    sacremoses=sacremoses.cli:cli
    """
    
    setup(
        name='sacremoses',
        packages=['sacremoses'],
        version='0.0.7',
        description='SacreMoses',
        long_description='LGPL MosesTokenizer in Python',
        author='',
        license='',
        package_data={'sacremoses': [
            'data/perluniprops/*.txt', 
            'data/nonbreaking_prefixes/nonbreaking_prefix.*'
        ]},
        url='https://github.com/alvations/sacremoses',
        keywords=[],
        classifiers=[],
        install_requires=['six', 'click', 'joblib', 'tqdm'],
        entry_points=console_scripts,
    )
    

    Command Handler

    In the referenced branch of your github repo, there is NO cli.py file. The [code] from your question needs to be saved in sacremoses/cli.py, and then combined with the suggested changes to your setup.py, everything should work fine.