Skip to content

[QUESTION] How to wrap commands #296

@mmcenti

Description

@mmcenti

First check

  • I used the GitHub search to find a similar issue and didn't find it.
  • I searched the Typer documentation, with the integrated search.
  • I already searched in Google "How to X in Typer" and didn't find any information.
  • I already searched in Google "How to X in Click" and didn't find any information.

Description

How can I wrap a command and extend the options?

I am able to do this via Click but haven't figured out a way to make it work. I want to be able to extend certain commands to give extra options when they are annotated.

Lets say I have a command defined as:

@app.command()
def hi(name: str = typer.Option(..., '--name', '-n', prompt=True, help="Name of person to say hi to"),):
    """ Say hello. """

    print(f"Hello, {name}!")

I can call this via python cli.py hi. Want I want is the ability to wrap the hi function to include a city and state if I wanted. Example:

def from_city(func,) -> "wrapper":
    @wraps(func)
    def wrapper(
        city: str = typer.Option(..., '--city', '-c', prompt=True, help='The name of the city to say hi from'),
        state: str = typer.Option("VA", '--state', '-s', help="The state you are saying hi from"),
    ):
        """ Setup for finding city. """
        # <do some stuff>
        return None
    return wrapper

@app.command()
@from_city
def hi_city(name: str = typer.Option(..., '--name', '-n', prompt=True, help="Name of person to say hi to"),):
    """ Say hello. """

    print(f"Hello, {name}. Welcome from {kwargs['city']}, {kwargs['state']}!")

By adding the @from_city annotation, I want the additional city/state options to be available.

Additional context

I can do this in Click with the following code:

def from_city(func) -> "wrapper":
    @click.pass_context
    @click.option(
        "--city",
        "-c",
        show_default=True,
        help="The name of the city to say hi from",
    )
    @click.option(
        "--state",
        "-s",
        default="VA",
        show_default=True,
        help="The state you are saying hi from",
    )
    @__wraps(func)
    def wrapper(*args, **kwargs):
        # Grab the context and put it in kwargs so the wrapped function has access
        kwargs["ctx"] = args[0]

        return

    return wrapper


@cli.command()
@from_city
@click.option(
    "--name",
    "-n",
    default="~/Downloads/pyshthreading.yaml",
    help="Location on disk to the cf template",
)
def test(*args, **kwargs):
    print(f"Hello, {kwargs['name']}. Welcome from {kwargs['city']}, {kwargs['state']}!")

Is there a way to do this in Typer?

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionQuestion or problem

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions