fastapi / typer

Typer, build great CLIs. Easy to code. Based on Python type hints.
https://typer.tiangolo.com/
MIT License
15.72k stars 669 forks source link

Have Typer help argument take precedence over main() docstring #350

Open ketozhang opened 2 years ago

ketozhang commented 2 years ago

First Check

Commit to Help

Example Code

"""MyProgram
This program does this and that.
"""
import typer

app = typer.Typer(help=__doc__)

@app.command()
def main():
    print("Hello, World!")

if __name__ == "__main__":
    app()

"""
$ python main.py --help
Usage: main.py [OPTIONS]

Options:
  --install-completion [bash|zsh|fish|powershell|pwsh]
                                  Install completion for the specified shell.
  --show-completion [bash|zsh|fish|powershell|pwsh]
                                  Show completion for the specified shell, to
                                  copy it or customize the installation.
  --help                          Show this message and exit.
"""

Description

Currently, if you have docstring on main(), the help argument in Typer() is ignored.

This feature is useful when you want both the CLI help pages to come from the module docstring.

Wanted Solution

Always show the help string in Typer(help=...). Either

Wanted Code

"""MyProgram
This program does this and that.
"""
import typer

app = typer.Typer(help=__doc__)

@app.command()
def main():
    print("Hello, World!")

if __name__ == "__main__":
    app()

"""
$ python main.py --help
Usage: main.py [OPTIONS]

MyProgram
This program does this and that.

Options:
  --install-completion [bash|zsh|fish|powershell|pwsh]
                                  Install completion for the specified shell.
  --show-completion [bash|zsh|fish|powershell|pwsh]
                                  Show completion for the specified shell, to
                                  copy it or customize the installation.
  --help                          Show this message and exit.
"""

Alternatives

Unfortunately this does not work.

"""MyProgram
This program does this and that.
"""
import typer

def main():
    f"""{__doc__}"""
    print("Hello, World!")

if __name__ == "__main__":
    typer.run(main)

Operating System

Linux, macOS

Operating System Details

No response

Typer Version

0.4.0

Python Version

Python 3.9.6

Additional Context

No response

ketozhang commented 2 years ago

I've found a workaround. It isn't ugly, but it is more boilerplate:

"""MyProgram
This program does this and that.
"""
import typer

def main():
    f"""{__doc__}"""
    print("Hello, World!")

if __name__ == "__main__":
    main.__doc__ = __doc__
    typer.run(main)

source