Code Monkey home page Code Monkey logo

Comments (6)

Nitinsiwach avatar Nitinsiwach commented on May 17, 2024 2

This should be made a part of the documentation. Great package otherwise

from typer.

JeromeK13 avatar JeromeK13 commented on May 17, 2024 1

Hey Guys

Yes this can be activated like this:

app = typer.Typer(chain=True)

from typer.

JeromeK13 avatar JeromeK13 commented on May 17, 2024 1
import typer

# Init CLI
cli = typer.Typer(chain=True)

@cli.command('my_command_name')
def my_function_name():
    typer.echo("Chain 1")

@cli.command('my_command_name2')
def my_function_name():
    typer.echo("Chain 2")

if __name__ == "__main__":
    cli()

So if you now run the CLI you can do the following (the command will execute in the order they provided)
python3 mycli.py my_command_name my_command_name2

from typer.

pmsoltani avatar pmsoltani commented on May 17, 2024 1

@JeromeK13 thanks for your prompt reply. I think perhaps "chaining commands" is not what I wanted. This is what I had in mind (using Click):

@click.command()
@click.option("--with-testdb/--no-with-testdb", default=False)
@click.pass_context
def reset(ctx):
    """Inits and seeds the database automatically."""
    ctx.invoke(init, with_testdb=with_testdb)
    ctx.invoke(seed)

    return None

After some fiddling with the code, I arrived at this:

@cli.command()
def reset(ctx: typer.Context, with_testdb: bool = False):
    """Inits and seeds the database automatically."""
    ctx.invoke(init, with_testdb)
    ctx.invoke(cyan)

Anyway, thanks again for your time.

from typer.

kalzoo avatar kalzoo commented on May 17, 2024

+1 (I think).

Edit: what I describe in my comment below is mostly a click problem, not a typer one! I had missed this fun discussion which pointed me the right way towards using click Context, and then the docs here became more relevant.

Solution, following the same example from [the docs] and my comments below:

import typer

app = typer.Typer

@app.callback()
def root(ctx: typer.Context, universe_name: str = typer.Option(None)):
    ctx.obj = universe_name

def universe_name_callback(ctx: typer.Context, value: Optional[str]):
    output = value or ctx.obj
    if not output:
        raise typer.BadParameter("--universe-name must be provided")
    return output

def conquer(universe_name: str = typer.Option(None, callback=universe_name_callback), reign_name: str = typer.Option(...)):
    typer.echo("Universe Name: " + universe_name)
    typer.echo("Reign Name: " + reign_name)

# this works
> python reigns.py --universe-name UNIVERSE_NAME conquer --reign-name REIGN_NAME

# this also works
> python reigns.py  conquer --reign-name REIGN_NAME --universe-name UNIVERSE_NAME

# this throws an error as expected
> python reigns.py  conquer --reign-name REIGN_NAME

However, this is clumsy and leaves plenty of room for error. It would still be nice if we could share options among different callbacks and commands, even if click is hostile to that idea.

I used ctx.obj for simplicity here but state would be no better. It meets the requirement for my use case so that's good. I could use click's pass decorators to do the rest, but since typer isn't compatible with those I'll leave it as is for now.

Hope this helps someone!


I'm packaging a CLI within a docker image, and it's important that I can configure the entrypoint with a root command and argument, but then that further arguments and commands can be appended as docker commands.

I've been all through the typer docs, which were a great intro - but without inline documentation in the code, the next step is to ask here.

For example:

Using the reigns example from your docs (loosely), imagine a command

python reigns.py UNIVERSE_NAME conquer REIGN_NAME

or something to that effect. I'd be just as happy with those as args or options - similar to how git itself allows mixing of args, flags, and options in almost any order. It does help that conquer remains a command, since that's the power of typer, otherwise we would just make everything an argument or option:

python reigns.py --universe_name UNIVERSE_NAME --operation conquer --reign_name REIGN_NAME

That discards much of what makes typer great and quick to set up, since everything is now packed into one root command. But it does allow me to draw a line between a static entrypoint and dynamic commands:

python reigns.py --universe_name UNIVERSE_NAME ||<entrypoint --- command>|| --operation conquer --reign_name REIGN_NAME

I did try just sending options out of order:

python reigns.py --universe_name UNIVERSE_NAME conquer REIGN_NAME
# Error: no such option: --universe_name

Putting it back in order fixed the error, but doesn't meet my docker ordering requirement:

# This works
python reigns.py  conquer REIGN_NAME --universe_name UNIVERSE_NAME

Best-case scenario, all commands in the tree would receive all options. Callbacks don't appear to serve this use case, since the option's value is needed by the command.

Is there a better way?

from typer.

pmsoltani avatar pmsoltani commented on May 17, 2024

@JeromeK13 would you please provide a more detailed example? How, for instance, do I name the command that executes other commands in sequence?

Appreciate your help in advance!

from typer.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.