Search code examples
pythoncommand-line-interfacepython-clickpython-poetry

Poetry manage python package CLI


I'm developing a Python package using Poetry with the following structure:

/packagename
 /packagename
  /tests
   __init__.py
   test_packagename.py
  __init__.py
  packagename.py
pyproject.toml

All the package code is inside packagename.py, which is imported in __init__.py.

I want to add a CLI and my goal is to execute the following in the command line:

<packagename> <packagefunction>

To do so, I used the click package for Python and wrote my <packagefunction> inside packagename.py as:

 @click.command()
 def packagefunction():

Currently, I have added entry points into poetry configuration file as:

[tool.poetry.scripts]
<packagefunction> = '<packagename>:<packagefunction>'

and run:

poetry run <packagefunction>

which execute perfectly.

However, I know this is not the correct way to do it and I want the CLI to execute with the commands shown above.


Solution

  • To achieve the command line you are after you, you can use a:

    click.Group()

    import click
    
    @click.group()
    def main():
        """packagename cli"""
    

    And then to use the group, you can use @main.command() decorator like:

    @main.command()
    def packagefunction():
        """packagefunction subcommand"""
    

    instead of @click.command() decorator.

    Poetry scripts

    To have poetry install packagename command and call the main group in the packagename module:

    [tool.poetry.scripts]
    # command_name = module_for_handler : function_for_handler
    <packagename> = '<packagename>:<main>'
    

    instead of:

    [tool.poetry.scripts]
    <packagefunction> = '<packagename>:<packagefunction>'