Metadata-Version: 2.1
Name: click_anno
Version: 0.1.1
Summary: UNKNOWN
Home-page: https://github.com/Cologler/click-anno-python
Author: Cologler
Author-email: skyoflw@gmail.com
License: MIT License
Description: # click-anno
        
        ![GitHub](https://img.shields.io/github/license/Cologler/click-anno-python.svg)
        [![Build Status](https://travis-ci.com/Cologler/click-anno-python.svg?branch=master)](https://travis-ci.com/Cologler/click-anno-python)
        [![PyPI](https://img.shields.io/pypi/v/click_anno.svg)](https://pypi.org/project/click-anno/)
        
        use annotation to create click app.
        
        ## Compare with click api
        
        ### Basic Arguments
        
        ``` py
        # click
        import click
        
        @click.command()
        @click.argument('filename')
        def touch(filename):
            click.echo(filename)
        
        # click_anno
        import click
        import click_anno
        
        @click_anno.command
        def touch(filename):
            click.echo(filename)
        ```
        
        ### Variadic Arguments
        
        ``` py
        # click
        import click
        
        @click.command()
        @click.argument('src', nargs=-1)
        @click.argument('dst', nargs=1)
        def copy(src, dst):
            for fn in src:
                click.echo('move %s to folder %s' % (fn, dst))
        
        # click_anno
        import click
        import click_anno
        
        @click_anno.command
        def copy(src: tuple, dst):
            for fn in src:
                click.echo('move %s to folder %s' % (fn, dst))
        ```
        
        ### Basic Value Options
        
        ``` py
        # click
        import click
        
        @click.command()
        @click.option('--n', default=1)
        def dots(n):
            click.echo('.' * n)
        
        # click_anno
        import click
        import click_anno
        
        @click_anno.command
        def dots(n=1):
            click.echo('.' * n)
        ```
        
        ### Required Value Options
        
        ``` py
        # click
        import click
        
        @click.command()
        @click.option('--n', required=True, type=int)
        def dots(n):
            click.echo('.' * n)
        
        # click_anno
        import click
        import click_anno
        
        @click_anno.command
        def dots(*, n: int):
            click.echo('.' * n)
        ```
        
        ### Multi Value Options
        
        ``` py
        # click
        import click
        
        @click.command()
        @click.option('--pos', nargs=2, type=float)
        def findme(pos):
            click.echo('%s / %s' % pos)
        
        # click_anno
        from typing import Tuple
        import click
        import click_anno
        
        @click_anno.command
        def findme(*, pos: Tuple[float, float]):
            click.echo('%s / %s' % pos)
        ```
        
        ### Tuples as Multi Value Options
        
        ``` py
        # click
        import click
        
        @click.command()
        @click.option('--item', type=(str, int))
        def putitem(item):
            click.echo('name=%s id=%d' % item)
        
        # click_anno
        from typing import Tuple
        import click
        import click_anno
        
        @click_anno.command
        def putitem(*, item: (str, int)):
            click.echo('name=%s id=%d' % item)
        ```
        
        ### Boolean Flags
        
        ``` py
        # click
        import click
        
        @click.command()
        @click.option('--shout', is_flag=True)
        def info(shout):
            click.echo(f'{shout!r}')
        
        # click_anno
        import click
        from click_anno import command
        from click_anno.types import flag
        
        @command
        def func(shout: flag):
            click.echo(f'{shout!r}')
        ```
        
        ### Inject Context
        
        ``` py
        # click
        @command()
        @click.pass_context
        def sync(ctx): # `ctx` must be the 1st arg
            click.echo(str(type(ctx)))
        
        # click_anno
        @command
        def sync(a, ctx: click.Context, b): # `ctx` can be any location
            click.echo(str(type(ctx)))
        ```
        
        ### Group
        
        ``` py
        # click
        @click.group()
        def cli():
            click.echo('Running')
        
        @cli.command()
        def sync():
            click.echo('Syncing')
        
        # click_anno
        @click_app
        class App:
            def __init__(self):
                click.echo('Running')
        
            def sync(self):
                click.echo('Syncing')
        ```
        
        ## Extensions
        
        ### Enum
        
        Enum is **NOT** `Choice`.
        
        ``` py
        # click
        # does not support
        
        # click_anno
        import click
        from click_anno import command
        from enum import Enum, auto
        
        class HashTypes(Enum):
            md5 = auto()
            sha1 = auto()
        
        @command
        def digest(hash_type: HashTypes):
            assert isinstance(hash_type, HashTypes)
            click.echo(hash_type)
        ```
        
        ### Alias
        
        ``` py
        # click
        # does not support
        
        # click_anno
        @click_app
        class App:
            def sync(self):
                click.echo('Syncing')
        
            alias = sync
        ```
        
        ### show default in argument
        
        by default, `click.argument` did not accept `show_default` option.
        
        click_anno was modify this.
        
        ``` py
        @command
        def func(a=10, *_):
            pass
        
        # with --help
        # Usage: func [OPTIONS] [A=10]
        # ...
        ```
        
        ## Arguments vs Options
        
        click only has two kinds of parameters:
        
        * Options
        * Arguments - work similarly to options but are positional.
        
        By default in python, arguments like `*args` and options like `**kwargs`.
        
        In example `func(a, b=1, *args, d, e=2)`, `a` `b` `args` are arguments, `d` `e` are options.
        
        If you don't want the args `*args`, rename it to `*_`.
        **click_anno will ignore all args named `_`**
        
        In example `func(a, b=1)`, `*args` did not exists. so `a` is argument, `b` is option.
        
        ## Auto Inject Arguments
        
        by default, you can inject `click.Context` by annotation:
        
        ``` py
        @command
        def inject_context(a, ctx: click.Context, b): # `ctx` can be any location
            click.echo(str(type(ctx)))
        ```
        
        or impl the `Injectable`:
        
        ``` py
        from click_anno import Injectable
        
        class Custom(Injectable):
            @classmethod
            def __inject__(cls):
                return cls()
        
        @command
        def inject_it(obj: Custom):
            assert isinstance(obj, Custom)
        ```
        
        or call `inject` function:
        
        ``` py
        from click_anno import inject
        
        class Custom: pass
        
        inject(Custom, lambda: Custom())
        
        @command
        def inject_it(obj: Custom):
            assert isinstance(obj, Custom)
        ```
        
        or if you want to inject from `click.Context.ensure_object()` or `click.Context.find_object()`, you can use:
        
        ``` py
        from click_anno import find, ensure
        
        @command
        def inject_it(f: find(A), e: ensure(B)):
            ...
        ```
        
Keywords: click
Platform: UNKNOWN
Description-Content-Type: text/markdown
