Metadata-Version: 2.1
Name: typed_cap
Version: 0.2.4
Summary: typed command line argument parser
Home-page: https://github.com/MamoruDS/typed-cap
Author: MamoruDS
Author-email: mamoruds.io@gmail.com
License: UNKNOWN
Description: # typed-cap
        
        [![pypi](https://img.shields.io/pypi/v/typed-cap?style=flat-square)](https://pypi.org/project/typed-cap/)
        [![style](https://img.shields.io/badge/code%20style-black-black?style=flat-square)](https://github.com/psf/black)
        
        Cap is a python **C**ommand-line **A**rgument **P**arser that provides **typing** support. Using Cap requires less code to generate a more robust parser.
        
        As you know python is a weakly typed programming language, and even if there is a typing module, its functionality is very weak compared to other languages like Typescript or Rust. We know it's ridiculous and pointless to compare python to any of these languages at the typing level, but properly handling these types in your code can really improve readability and reduce typing errors. And that gave us the motivation to write this package.
        
        ## Usage
        
        ⚠️ `typed_cap` required `python>=3.8`
        
        ```
        pip install typed_cap
        ```
        
        ### Quick Example
        
        ```python
        # python>=3.9 only
        from typed_cap import Cap, helpers, annotation_extra as anno
        from typing import Annotated, List, Optional, TypedDict
        
        
        class T(TypedDict):
            verbose: Annotated[bool, anno("v", "verbose output")]
            message: Annotated[List[str], anno("m", about="your messages")]
            size: Annotated[Optional[float], anno(alias="n", about="optional number")]
        
        
        cap = Cap(T)
        ```
        
        ```python
        from typed_cap import Cap, helpers
        from typing import List, Optional, TypedDict
        
        
        class T(TypedDict):
            verbose: bool
            message: List[str]
            size: Optional[float]
        
        
        cap = Cap(T)
        cap.default(
            {
                "verbose": False,
            }
        )
        cap.helper(
            {
                "verbose": {
                    "alias": "v",
                    "about": "verbose output",
                },
                "message": {"alias": "m", "about": "your messages"},
                "size": {
                    "alias": "n",
                    "about": "optional number",
                },
            }
        )
        helpers["arg_help"](cap, "help", None)
        helpers["arg_version"](cap, "version", "V")
        args = cap.parse()
        
        print(args.args)
        print(args.val)
        ```
        
        ```shell
        python demo.py
        # DEMO: option 'message':list[str] is required but it is missing
        
        python demo.py -vv -m="msg1" --message "msg2" -m "msg3" -n=0.1 -n=10 ~/.config
        # ['/home/local/.config']
        # {'verbose': True, 'message': ['msg1', 'msg2', 'msg3'], 'size': 10.0}
        ```
        
        ## Features
        
        ### Flags
        
        flags are `bool` fields defined in input type
        
        ```python
        class T(TypedDict):
            silent: bool
            yes: Optional[bool]
        ...
        args = cap.parse()
        yes = args.val['yes']
        ```
        
        -   alias for flags and options
            adds short-version for convenient
            ```python
            cap.helper(
                { "ipv4": "4" }
            )
            ```
            `-4` equals to `--ipv4`
        -   supports combining alias
            `-zxvf` equals to `-z -x -v -f`
        -   supports multiple occurrences
            `-v -v` or `-vv`
            how to get occurrences of the argument
            ```python
            class T(TypedDict):
                ...
                verbose: bool
            ...
            args.count('verbose') # -> int
            ```
        
        ### Option Argument
        
        named options which are take values
        
        ```python
        class T(TypedDict):
            integer: int
            floating: float
            strings: List[str]
        ```
        
        -   supports adding alias
            ```python
            cap.helper(
                {
                    {"integer": {"alias": "i"}},
                    {"floating": {"alias": "f"}},
                    {"strings": {"alias": "s"}},
                }
            )
            ```
            `-i 1` `-i=1` `--integer 1` `--integer=1`
        -   supports multiple values
            `-m="msg1" --message "msg2" -m "msg3"`
            will get
            ```python
            { 'message': ['msg1', 'msg2', 'msg3'] }
            ```
        
        ### Typing
        
        Cap accepts an arbitrary [TypedDict](https://docs.python.org/3.9/library/typing.html#typing.TypedDict) instance `T` to get the values that satisfy the predefined parameters and their types via the built-in validator. After parser execution you will get a `dict` that strictly satisfies type `T`. The nice thing about this is that you can leverage features such as auto-completion and type checking from modern editors.
        
        <p align="center">
            <img width="550px" src="https://github.com/MamoruDS/typed-cap/raw/main/screenshots/clip00.gif">
        </p>
        
        The preset validator currently supports:
        
        -   `bool`
        -   `int`
        -   `float`
        -   `str`
        -   `NoneType`
        -   `Union`
            including `Optional` (e.g. `Optional[int]` equals `Union[int, None]`)
        -   queue
            `list` and `tuple`
        -   `Literal`
        
        Check the supported types in the preset validator from [here](https://github.com/MamoruDS/typed-cap/blob/dev/typed_cap/typing.py#L241-L292).
        
        #### Custom validator
        
        TODO: build your validator with `ValidVal`
        
        ```python
        from typed_cap.typing import ValidVal
        ...
        ```
        
        ### Helpers
        
        Cap proviedes some useful argument helpers
        
        -   `help`
            generate help documents that automatically adapt to the terminal width
            usage:
            ```python
            helpers["arg_help"](
                cap: Cap,
                name: str,
                alias: Optional[VALID_ALIAS_CANDIDATES],
            ) -> None
            ```
            example:
            ```python
            from typed_cap import Cap, helpers
            ... # code from quick example
            cap.about("some descriptions") # optional
            helpers["arg_help"](cap, "help", None)
            args = cap.parse()
            ```
            ```shell
            python demo.py --help
            # some descriptions
            #
            # OPTIONS:
            #     -v,--verbose    verbose output
            #     -m,--message    your messages
            #     -n,--size       optional number
            #        --help       display the help text
            ```
        -   `version`
            usage:
        
            ```python
            helpers["arg_help"](
                cap: Cap,
                name: str,
                alias: Optional[VALID_ALIAS_CANDIDATES],
            ) -> None
            ```
        
            example:
        
            ```python
            from typed_cap import Cap, helpers
            ... # code from quick example
            cap.name("your-demo") # optional
            cap.version("0.1.0")
            helpers["arg_version"](cap, "version", "V")
            args = cap.parse()
            ```
        
            ```shell
            python demo.py -V # or
            python demo.py --version
            # your-demo 0.1.0
            ```
        
        ### Others
        
        using `Cap.raw_exception` to expose exceptions
        
        ## Examples
        
        ### Basic Example
        
        ```python
        from typed_cap import Cap
        from typing import Optional, TypedDict
        
        
        class T(TypedDict):
            all: Optional[bool]
            total: Optional[bool]
            max_depth: Optional[int]
            human_readable: Optional[bool]
        
        
        cap = Cap(T)
        args = cap.parse()
        
        print(args.args)
        print(args.val)
        ```
        
        ```shell
        python demo.py --all --total /opt
        # ['/opt']
        # {'all': True, 'total': True, 'max_depth': None, 'human_readable': None}
        ```
        
        ### Advance Example
        
        ```python
        from typed_cap import Cap, helpers
        from typing import Optional, TypedDict
        
        
        class T(TypedDict):
            all: bool
            total: bool
            max_depth: int
            human_readable: Optional[bool]
        
        
        cap = Cap(T)
        cap.default(
            {
                "all": False,
                "total": False,
                "max_depth": -1,
            }
        )
        cap.helper(
            {
                "all": {
                    "alias": "a",
                    "about": "write counts for all files, not just directories",
                },
                "total": {"alias": "c", "about": "produce a grand total"},
                "max_depth": {
                    "alias": "d",
                    "about": "print the total for a directory (or file, with --all) only if it is N or fewer levels below the command line argument;",
                },
                "human_readable": {
                    "alias": "h",
                    "about": "print sizes in human readable format (e.g., 1K 234M 2G)",
                },
            }
        )
        helpers["arg_help"](cap, 'help')
        args = cap.parse()
        
        print(args.args)
        print(args.val)
        ```
        
        ```shell
        python demo.py -ah --max-depth=1 /tmp
        # ['/tmp']
        # {'all': True, 'human_readable': True, 'max_depth': 1, 'total': False}
        ```
        
Platform: UNKNOWN
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Requires-Python: >=3.8
Description-Content-Type: text/markdown
