Skip to content

Commit

Permalink
Merge branch 'master' into lachaib/issue181
Browse files Browse the repository at this point in the history
  • Loading branch information
svlandeg committed Apr 2, 2024
2 parents 2a48587 + 8bac821 commit 19319c6
Show file tree
Hide file tree
Showing 79 changed files with 2,131 additions and 264 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/build-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ jobs:
id: cache
with:
path: ${{ env.pythonLocation }}
key: ${{ runner.os }}-python-docs-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml', 'requirements-docs.txt') }}-v01
key: ${{ runner.os }}-python-docs-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml', 'requirements-docs.txt') }}-v02
- name: Install docs extras
if: steps.cache.outputs.cache-hit != 'true'
run: pip install -r requirements-docs.txt
- name: Install Material for MkDocs Insiders
if: ( github.event_name != 'pull_request' || github.secret_source != 'Actions' ) && steps.cache.outputs.cache-hit != 'true'
if: ( github.event_name != 'pull_request' || github.secret_source == 'Actions' ) && steps.cache.outputs.cache-hit != 'true'
run: |
pip install git+https://${{ secrets.TYPER_MKDOCS_MATERIAL_INSIDERS }}@github.com/squidfunk/mkdocs-material-insiders.git
pip install git+https://${{ secrets.TYPER_MKDOCS_MATERIAL_INSIDERS }}@github.com/pawamoy-insiders/griffe-typing-deprecated.git
Expand All @@ -71,7 +71,7 @@ jobs:
if: github.event_name == 'pull_request' && github.secret_source != 'Actions'
run: python -m mkdocs build
- name: Build Docs with Insiders
if: ( github.event_name != 'pull_request' || github.secret_source != 'Actions' )
if: ( github.event_name != 'pull_request' || github.secret_source == 'Actions' )
run: python -m mkdocs build --config-file mkdocs.insiders.yml

- uses: actions/upload-artifact@v3
Expand Down
23 changes: 12 additions & 11 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ on:
jobs:
publish:
runs-on: ubuntu-latest
strategy:
matrix:
package:
- typer-slim
- typer
- typer-cli
env:
dir: ${{ matrix.package == 'typer-slim' && './' || matrix.package == 'typer' && 'typer_package' || matrix.package == 'typer-cli' && 'typer_cli_package' }}
permissions:
id-token: write
steps:
- name: Dump GitHub context
env:
Expand All @@ -21,21 +31,12 @@ jobs:
# Issue ref: https://github.com/actions/setup-python/issues/436
# cache: "pip"
# cache-dependency-path: pyproject.toml
- uses: actions/cache@v3
id: cache
with:
path: ${{ env.pythonLocation }}
key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}
- name: Install build dependencies
if: steps.cache.outputs.cache-hit != 'true'
run: pip install build
- name: Build distribution
working-directory: ${{ env.dir }}
run: python -m build
- name: Publish
uses: pypa/gh-action-pypi-publish@v1.8.11
with:
password: ${{ secrets.PYPI_API_TOKEN }}
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
packages-dir: ${{ env.dir }}/dist/
60 changes: 60 additions & 0 deletions .github/workflows/test-redistribute.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Test Redistribute

on:
push:
branches:
- master
pull_request:
types:
- opened
- synchronize

jobs:
test-redistribute:
runs-on: ubuntu-latest
strategy:
matrix:
package:
- typer-slim
- typer
- typer-cli
env:
dir: ${{ matrix.package == 'typer-slim' && './' || matrix.package == 'typer' && 'typer_package' || matrix.package == 'typer-cli' && 'typer_cli_package' }}
steps:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.10"
# Issue ref: https://github.com/actions/setup-python/issues/436
# cache: "pip"
# cache-dependency-path: pyproject.toml
- name: Install build dependencies
run: pip install build
- name: Build source distribution
working-directory: ${{ env.dir }}
run: python -m build --sdist
- name: Decompress source distribution
working-directory: ${{ env.dir }}
run: |
cd dist
tar xvf typer*.tar.gz
- name: Install test dependencies
if: ${{ matrix.package == 'typer-slim' }}
run: |
cd dist/typer*/
pip install -r requirements-tests.txt
- name: Run source distribution tests
if: ${{ matrix.package == 'typer-slim' }}
run: |
cd dist/typer*/
bash scripts/test.sh
- name: Build wheel distribution
working-directory: ${{ env.dir }}
run: |
cd dist
pip wheel --no-deps typer*.tar.gz
4 changes: 4 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ on:
types:
- opened
- synchronize
schedule:
# cron every week on monday
- cron: "0 0 * * 1"

jobs:
test:
Expand Down Expand Up @@ -40,6 +43,7 @@ jobs:
- name: Lint
run: bash scripts/lint.sh
- run: mkdir coverage
- run: bash ./scripts/test-files.sh
- name: Test
run: bash scripts/test.sh
env:
Expand Down
117 changes: 93 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,46 +28,96 @@

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 that you can use to run scripts, automatically converting them to CLIs, even if they don't use Typer internally.

## FastAPI of CLIs

<a href="https://fastapi.tiangolo.com" target="_blank"><img src="https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" style="width: 20%;"></a>

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

And it's intended to be the FastAPI of CLIs.

## Requirements

**Typer** stands on the shoulders of a giant. Its only internal dependency is <a href="https://click.palletsprojects.com/" class="external-link" target="_blank">Click</a>.
**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

<div class="termy">

```console
$ pip install "typer[all]"
$ pip install typer
---> 100%
Successfully installed typer
Successfully installed typer rich shellingham
```

</div>

**Note**: that will include <a href="https://rich.readthedocs.io/" class="external-link" target="_blank">Rich</a>. Rich is the recommended library to *display* information on the terminal, it is optional, but when installed, it's deeply integrated into **Typer** to display beautiful output.

## 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

Expand All @@ -80,9 +130,7 @@ if __name__ == "__main__":
typer.run(main)
```

### Run it

Run your application:
Now you could run it with Python directly:

<div class="termy">

Expand Down Expand Up @@ -120,7 +168,7 @@ Hello Camila

</div>

**Note**: auto-completion works when you create a Python package and run it with `--install-completion` or when you use <a href="https://typer.tiangolo.com/typer-cli/" class="internal-link" target="_blank">Typer CLI</a>.
**Note**: you can also call this same script with the `typer` command, but you don't need to.

## Example upgrade

Expand Down Expand Up @@ -293,22 +341,43 @@ And similarly for **files**, **paths**, **enums** (choices), etc. And there are

**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 <a href="https://typer.tiangolo.com/typer-cli/" class="internal-link" target="_blank">Typer CLI</a>.
**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>.

## Optional Dependencies
## Dependencies

Typer uses <a href="https://click.palletsprojects.com/" class="external-link" target="_blank">Click</a> internally. That's the only dependency.
**Typer** stands on the shoulders of a giant. Its only internal required dependency is <a href="https://click.palletsprojects.com/" class="external-link" target="_blank">Click</a>.

But you can also install extras:
By default it also comes with extra standard dependencies:

* <a href="https://rich.readthedocs.io/en/stable/index.html" class="external-link" target="_blank"><code>rich</code></a>: and Typer will show nicely formatted errors automatically.
* <a href="https://github.com/sarugaku/shellingham" class="external-link" target="_blank"><code>shellingham</code></a>: and Typer will automatically detect the current shell when installing completion.
* <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.
* With `shellingham` you can just use `--install-completion`.
* Without `shellingham`, you have to pass the name of the shell to install completion for, e.g. `--install-completion bash`.
* `typer-cli`: adds the `typer` command to your shell:
* Quickly run scripts (that don't have to use Typer) with shell completion.
* Generate docs for your Typer applications.

### `typer-slim`

If you don't want the extra dependencies, install `typer-slim` instead.

When you install with:

```bash
pip install typer
```

...it's the equivalent of:

```bash
pip install "typer-slim[standard]"
```

The `standard` extra dependencies are `rich`, `shellingham`, `typer-cli`.

You can install `typer` with `rich` and `shellingham` with `pip install typer[all]`.
**Note**: even if you don't install `typer-cli` you can still use it's functionality by calling `typer` as a module, e.g. `python -m typer`.

## License

Expand Down
8 changes: 4 additions & 4 deletions docs/features.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,16 @@ The resulting CLI apps created with **Typer** have the nice features of many "pr
* Automatic completion for the CLI app in all operating systems, in all the shells (Bash, Zsh, Fish, PowerShell), so that the final user of your app can just hit <kbd>TAB</kbd> and get the available options or subcommands. *

!!! note "* Auto completion"
Auto completion works when you create a package (installable with `pip`). Or when using [Typer CLI](typer-cli.md){.internal-link target=_blank}.
Auto completion works when you create a package (installable with `pip`). Or when using the `typer` command.

If you also add `shellingham` as a dependency, **Typer** will use it to auto-detect the current shell when installing completion.
**Typer** uses `shellingham` to auto-detect the current shell when installing completion. If you don't want to include `shellingham`, install `typer-slim`.

**Typer** will automatically create 2 *CLI options*:

* `--install-completion`: Install completion for the current shell.
* `--show-completion`: Show completion for the current shell, to copy it or customize the installation.

If you didn't add `shellingham` those *CLI options* take a value with the name of the shell to install completion for, e.g.:
If you didn't add `shellingham` (if you installed `pip install typer-slim`) those *CLI options* take a value with the name of the shell to install completion for, e.g.:

* `--install-completion bash`.
* `--show-completion powershell`.
Expand All @@ -74,7 +74,7 @@ The resulting CLI apps created with **Typer** have the nice features of many "pr

<a href="https://click.palletsprojects.com" class="external-link" target="_blank">Click</a> is one of the most popular tools for building CLIs in Python.

**Typer** is based on it, so you get all its benefits, plug-ins, robustness, etc.
**Typer** is based on it, so you get all its benefits.

But you can write simpler code with the benefits of modern Python.

Expand Down

0 comments on commit 19319c6

Please sign in to comment.