Metadata-Version: 2.4
Name: doctyper
Version: 0.24.1.post6
Summary: Wrapper around Typer using Google-Doc strings for CLI descriptions.
Author-Email: =?utf-8?q?Sebasti=C3=A1n_Ram=C3=ADrez?= <tiangolo@gmail.com>
Maintainer-Email: =?utf-8?q?Tim_H=C3=B6rmann?= <pypi@audivir.de>
License-Expression: MIT
License-File: LICENSE
Classifier: Intended Audience :: Information Technology
Classifier: Intended Audience :: System Administrators
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Software Development
Classifier: Typing :: Typed
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Project-URL: Homepage, https://github.com/audivir/doctyper
Project-URL: Documentation, https://typer.tiangolo.com
Project-URL: Repository, https://github.com/audivir/doctyper
Project-URL: Issues, https://github.com/audivir/doctyper/issues
Project-URL: Changelog, https://typer.tiangolo.com/release-notes/
Requires-Python: >=3.10
Requires-Dist: typing-extensions
Requires-Dist: docstring-parser
Requires-Dist: eval-type-backport
Requires-Dist: click>=8.2.1
Requires-Dist: shellingham>=1.3.0
Requires-Dist: rich>=12.3.0
Requires-Dist: annotated-doc>=0.0.2
Description-Content-Type: text/markdown

# doctyper

> It is fully compatible with `typer`'s API (use with `import doctyper as typer`)
> all specific features are activated via keyword arguments.

A wrapper around [Typer](https://typer.tiangolo.com) to simplify the creation of command-line interfaces (CLIs).
It uses parsed docstrings to extract arguments and options for CLI commands.

## Features

* Use Google-style docstrings to generate help text for arguments and options.
* Support type-aliased identifiers.
* Interpret `Literal` types (for choices) (now partially available in upstream Typer):
  * Interpret unions, lists, or tuples of `Literal`s (not yet available upstream).
  * Check for uniqueness in `Literal`s/Enums (e.g. `Literal["1", 1]` would break type safety).
* Disable completion and pretty tracebacks by default.
* Enable `str | None` type hints.
* Show `[default: None]` for clarity.

## Example

```python
from typing import Annotated, Literal

import doctyper
from typing_extensions import TypeAliasType

Alias = TypeAliasType("Alias", int)  # in >=3.12: type Alias = int


def main(
    arg: str,  # disables [default: None] in output
    ann_arg: Annotated[str, typer.Argument(help="Supersedes help from docstring.")],
    alias_arg: Alias,  # output original name
    lit_arg: Literal["arg", "other"],  # only strings allowed for literals
    lit_opt: Literal["opt"]
    | Literal["other"] = "opt",  # only unions of literals are supported
    ann_opt: Annotated[int, typer.Option(help="Supersedes help from docstring.")] = 1,
    other: int = 1,
    str_or_none: str | None = None,  # enable "str | None" type hints
    flag: bool = False,
) -> None:
    """Run the main application.

    Args:
        arg: String argument.
        ann_arg: This will not be used.
        alias_arg: Argument using an aliased identifier.
        other: Integer argument with a default.
        lit_arg: Argument with choices.
        lit_opt: Option with choices and a default.
        ann_opt: This will not be used.
        str_or_none: String argument with a default of None.
        flag: Boolean flag.
    """


if __name__ == "__main__":
    app = doctyper.DocTyper()
    app.command()(main)
    app()
```

```console
 Usage: t.py [OPTIONS] ARG ANN_ARG ALIAS_ARG LIT_ARG:{arg|other}

 Run the main application.


╭─ Arguments ──────────────────────────────────────────────────────────────────────────────────────╮
│ *    arg            TEXT                 String argument. [required]                             │
│ *    ann_arg        TEXT                 Supersedes help from docstring. [required]              │
│ *    alias_arg      INTEGER              Argument using an aliased identifier. [required]       │
│ *    lit_arg        LIT_ARG:{arg|other}  Argument with choices. [required]                      │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Options ────────────────────────────────────────────────────────────────────────────────────────╮
│ --lit-opt                     [opt|other]  Option with choices and a default. [default: opt]    │
│ --ann-opt                     INTEGER      Supersedes help from docstring. [default: 1]         │
│ --other                       INTEGER      Integer argument with a default. [default: 1]        │
│ --str-or-none                 TEXT         String argument with a default of None.              │
│                                            [default: None]                                      │
│ --flag           --no-flag                 Boolean flag. [default: no-flag]                     │
│ --help                                     Show this message and exit.                          │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
```

## Configuration

| Keyword Argument        | Description                                                                 |
|--------------------------|-----------------------------------------------------------------------------|
| `parse_docstrings`       | Parse Google-style docstrings to generate help text for arguments/options. |
| `show_none_defaults`     | Explicitly show `[default: None]` for parameters with a default of `None`. |

## Testing

To run `typer`'s test suite including extra tests for `doctyper` run `python test_doctyper.py`.

---

<p align="center">
  <a href="https://typer.tiangolo.com"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg#only-light" alt="Typer"></a>

</p>
<p align="center">
    <em>Typer, build great CLIs. Easy to code. Based on Python type hints.</em>
</p>
<p align="center">
<a href="https://github.com/fastapi/typer/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
    <img src="https://github.com/fastapi/typer/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Test">
</a>
<a href="https://github.com/fastapi/typer/actions?query=workflow%3APublish" target="_blank">
    <img src="https://github.com/fastapi/typer/workflows/Publish/badge.svg" alt="Publish">
</a>
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/typer" target="_blank">
    <img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/typer.svg" alt="Coverage">
<a href="https://pypi.org/project/typer" target="_blank">
    <img src="https://img.shields.io/pypi/v/typer?color=%2334D058&label=pypi%20package" alt="Package version">
</a>
</p>

---

**Documentation**: <a href="https://typer.tiangolo.com" target="_blank">https://typer.tiangolo.com</a>

**Source Code**: <a href="https://github.com/fastapi/typer" target="_blank">https://github.com/fastapi/typer</a>

---

Typer is a library for building <abbr title="command line interface, programs executed from a terminal">CLI</abbr> applications that users will **love using** and developers will **love creating**. Based on Python type hints.

It's also a command line tool to run scripts, automatically converting them to CLI applications.

The key features are:

* **Intuitive to write**: Great editor support. <abbr title="also known as auto-complete, autocompletion, IntelliSense">Completion</abbr> everywhere. Less time debugging. Designed to be easy to use and learn. Less time reading docs.
* **Easy to use**: It's easy to use for the final users. Automatic help, and automatic completion for all shells.
* **Short**: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs.
* **Start simple**: The simplest example adds only 2 lines of code to your app: **1 import, 1 function call**.
* **Grow large**: Grow in complexity as much as you want, create arbitrarily complex trees of commands and groups of subcommands, with options and arguments.
* **Run scripts**: Typer includes a `typer` command/program that you can use to run scripts, automatically converting them to CLIs, even if they don't use Typer internally.

## FastAPI of CLIs

**Typer** is <a href="https://fastapi.tiangolo.com" class="external-link" target="_blank">FastAPI</a>'s little sibling, it's the FastAPI of CLIs.

## Installation

Create and activate a <a href="https://typer.tiangolo.com/virtual-environments/" class="external-link" target="_blank">virtual environment</a> and then install **Typer**:

<div class="termy">

```console
$ pip install typer
---> 100%
Successfully installed typer rich shellingham
```

</div>

## Example

### The absolute minimum

* Create a file `main.py` with:

```Python
def main(name: str):
    print(f"Hello {name}")
```

This script doesn't even use Typer internally. But you can use the `typer` command to run it as a CLI application.

### Run it

Run your application with the `typer` command:

<div class="termy">

```console
// Run your application
$ typer main.py run

// You get a nice error, you are missing NAME
Usage: typer [PATH_OR_MODULE] run [OPTIONS] NAME
Try 'typer [PATH_OR_MODULE] run --help' for help.
╭─ Error ───────────────────────────────────────────╮
│ Missing argument 'NAME'.                          │
╰───────────────────────────────────────────────────╯


// You get a --help for free
$ typer main.py run --help

Usage: typer [PATH_OR_MODULE] run [OPTIONS] NAME

Run the provided Typer app.

╭─ Arguments ───────────────────────────────────────╮
│ *    name      TEXT  [default: None] [required]   |
╰───────────────────────────────────────────────────╯
╭─ Options ─────────────────────────────────────────╮
│ --help          Show this message and exit.       │
╰───────────────────────────────────────────────────╯

// Now pass the NAME argument
$ typer main.py run Camila

Hello Camila

// It works! 🎉
```

</div>

This is the simplest use case, not even using Typer internally, but it can already be quite useful for simple scripts.

**Note**: auto-completion works when you create a Python package and run it with `--install-completion` or when you use the `typer` command.

## Use Typer in your code

Now let's start using Typer in your own code, update `main.py` with:

```Python
import typer


def main(name: str):
    print(f"Hello {name}")


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

Now you could run it with Python directly:

<div class="termy">

```console
// Run your application
$ python main.py

// You get a nice error, you are missing NAME
Usage: main.py [OPTIONS] NAME
Try 'main.py --help' for help.
╭─ Error ───────────────────────────────────────────╮
│ Missing argument 'NAME'.                          │
╰───────────────────────────────────────────────────╯


// You get a --help for free
$ python main.py --help

Usage: main.py [OPTIONS] NAME

╭─ Arguments ───────────────────────────────────────╮
│ *    name      TEXT  [default: None] [required]   |
╰───────────────────────────────────────────────────╯
╭─ Options ─────────────────────────────────────────╮
│ --help          Show this message and exit.       │
╰───────────────────────────────────────────────────╯

// Now pass the NAME argument
$ python main.py Camila

Hello Camila

// It works! 🎉
```

</div>

**Note**: you can also call this same script with the `typer` command, but you don't need to.

## Example upgrade

This was the simplest example possible.

Now let's see one a bit more complex.

### An example with two subcommands

Modify the file `main.py`.

Create a `typer.Typer()` app, and create two subcommands with their parameters.

```Python hl_lines="3  6  11  20"
import typer

app = typer.Typer()


@app.command()
def hello(name: str):
    print(f"Hello {name}")


@app.command()
def goodbye(name: str, formal: bool = False):
    if formal:
        print(f"Goodbye Ms. {name}. Have a good day.")
    else:
        print(f"Bye {name}!")


if __name__ == "__main__":
    app()
```

And that will:

* Explicitly create a `typer.Typer` app.
    * The previous `typer.run` actually creates one implicitly for you.
* Add two subcommands with `@app.command()`.
* Execute the `app()` itself, as if it was a function (instead of `typer.run`).

### Run the upgraded example

Check the new help:

<div class="termy">

```console
$ python main.py --help

 Usage: main.py [OPTIONS] COMMAND [ARGS]...

╭─ Options ─────────────────────────────────────────╮
│ --install-completion          Install completion  │
│                               for the current     │
│                               shell.              │
│ --show-completion             Show completion for │
│                               the current shell,  │
│                               to copy it or       │
│                               customize the       │
│                               installation.       │
│ --help                        Show this message   │
│                               and exit.           │
╰───────────────────────────────────────────────────╯
╭─ Commands ────────────────────────────────────────╮
│ goodbye                                           │
│ hello                                             │
╰───────────────────────────────────────────────────╯

// When you create a package you get ✨ auto-completion ✨ for free, installed with --install-completion

// You have 2 subcommands (the 2 functions): goodbye and hello
```

</div>

Now check the help for the `hello` command:

<div class="termy">

```console
$ python main.py hello --help

 Usage: main.py hello [OPTIONS] NAME

╭─ Arguments ───────────────────────────────────────╮
│ *    name      TEXT  [default: None] [required]   │
╰───────────────────────────────────────────────────╯
╭─ Options ─────────────────────────────────────────╮
│ --help          Show this message and exit.       │
╰───────────────────────────────────────────────────╯
```

</div>

And now check the help for the `goodbye` command:

<div class="termy">

```console
$ python main.py goodbye --help

 Usage: main.py goodbye [OPTIONS] NAME

╭─ Arguments ───────────────────────────────────────╮
│ *    name      TEXT  [default: None] [required]   │
╰───────────────────────────────────────────────────╯
╭─ Options ─────────────────────────────────────────╮
│ --formal    --no-formal      [default: no-formal] │
│ --help                       Show this message    │
│                              and exit.            │
╰───────────────────────────────────────────────────╯

// Automatic --formal and --no-formal for the bool option 🎉
```

</div>

Now you can try out the new command line application:

<div class="termy">

```console
// Use it with the hello command

$ python main.py hello Camila

Hello Camila

// And with the goodbye command

$ python main.py goodbye Camila

Bye Camila!

// And with --formal

$ python main.py goodbye --formal Camila

Goodbye Ms. Camila. Have a good day.
```

</div>

**Note**: If your app only has one command, by default the command name is **omitted** in usage: `python main.py Camila`. However, when there are multiple commands, you must **explicitly include the command name**: `python main.py hello Camila`. See [One or Multiple Commands](https://typer.tiangolo.com/tutorial/commands/one-or-multiple/) for more details.

### Recap

In summary, you declare **once** the types of parameters (*CLI arguments* and *CLI options*) as function parameters.

You do that with standard modern Python types.

You don't have to learn a new syntax, the methods or classes of a specific library, etc.

Just standard **Python**.

For example, for an `int`:

```Python
total: int
```

or for a `bool` flag:

```Python
force: bool
```

And similarly for **files**, **paths**, **enums** (choices), etc. And there are tools to create **groups of subcommands**, add metadata, extra **validation**, etc.

**You get**: great editor support, including **completion** and **type checks** everywhere.

**Your users get**: automatic **`--help`**, **auto-completion** in their terminal (Bash, Zsh, Fish, PowerShell) when they install your package or when using the `typer` command.

For a more complete example including more features, see the <a href="https://typer.tiangolo.com/tutorial/">Tutorial - User Guide</a>.

## Dependencies

**Typer** stands on the shoulders of giants. It has three required dependencies:

* <a href="https://click.palletsprojects.com/" class="external-link" target="_blank">Click</a>: a popular tool for building CLIs in Python. Typer is based on it.
* <a href="https://rich.readthedocs.io/en/stable/index.html" class="external-link" target="_blank"><code>rich</code></a>: to show nicely formatted errors automatically.
* <a href="https://github.com/sarugaku/shellingham" class="external-link" target="_blank"><code>shellingham</code></a>: to automatically detect the current shell when installing completion.

### `typer-slim`

There used to be a slimmed-down version of Typer called `typer-slim`, which didn't include the dependencies `rich` and `shellingham`, nor the `typer` command.

However, since version 0.22.0, we have stopped supporting this, and `typer-slim` now simply installs (all of) Typer.

If you want to disable Rich globally, you can set an environmental variable `TYPER_USE_RICH` to `False` or `0`.

## License

This project is licensed under the terms of the MIT license.
