<commit_before>When you create a CLI program with **Typer** you probably want to create your own Python package.

That's what allows your users to install it and have it as an independent program that they can use in their terminal.

And that's also required for shell auto completion to work (unless you use your program through [Typer CLI](../typer-cli.md){.internal-link target=_blank}).

Nowadays, there are several ways and tools to create Python packages (what you install with `pip install something`).

You might even have your favorite already.

Here's a very opinionated, short guide, showing one of the alternative ways of creating a Python package with a **Typer** app, from scratch.

!!! tip
    If you already have a favorite way of creating Python packages, feel free to skip this.

## Prerequisites

For this guide we'll use <a href="https://python-poetry.org/" class="external-link" target="_blank">Poetry</a>.

Poetry's docs are great, so go ahead, check them and install it.

## Create a project

Let's say we want to create a CLI application called `portal-gun`.

To make sure your package doesn't collide with the package created by someone else, we'll name it with a prefix of your name.

So, if your name is Rick, we'll call it `rick-portal-gun`.

Create a project with Poetry:

<div class="termy">

```console
$ poetry new rick-portal-gun

Created package rick_portal_gun in rick-portal-gun

// Enter the new project directory
cd ./rick-portal-gun
```

</div>

## Dependencies and environment

Add `typer[all]` to your dependencies:

<div class="termy">

```console
$ poetry add typer[all]

// It creates a virtual environment for your project
Creating virtualenv rick-portal-gun-w31dJa0b-py3.6 in /home/rick/.cache/pypoetry/virtualenvs
Using version ^0.1.0 for typer

Updating dependencies
Resolving dependencies... (1.2s)

Writing lock file

---> 100%

Package operations: 15 installs, 0 updates, 0 removals

  - Installing zipp (3.1.0)
  - Installing importlib-metadata (1.5.0)
  - Installing pyparsing (2.4.6)
  - Installing six (1.14.0)
  - Installing attrs (19.3.0)
  - Installing click (7.1.1)
  - Installing colorama (0.4.3)
  - Installing more-itertools (8.2.0)
  - Installing packaging (20.3)
  - Installing pluggy (0.13.1)
  - Installing py (1.8.1)
  - Installing shellingham (1.3.2)
  - Installing wcwidth (0.1.8)
  - Installing pytest (5.4.1)
  - Installing typer (0.0.11)

// Activate that new virtual environment
$ poetry shell

Spawning shell within /home/rick/.cache/pypoetry/virtualenvs/rick-portal-gun-w31dJa0b-py3.6

// Open an editor using this new environment, for example VS Code
$ code ./
```

</div>

You can see that you have a generated project structure that looks like:

```
.
├── poetry.lock
├── pyproject.toml
├── README.rst
├── rick_portal_gun
│   └── __init__.py
└── tests
    ├── __init__.py
    └── test_rick_portal_gun.py
```

## Create your app

Now let's create an extremely simple **Typer** app.

Create a file `rick_portal_gun/main.py` with:

```Python
import typer


app = typer.Typer()


@app.callback()
def callback():
    """
    Awesome Portal Gun
    """


@app.command()
def shoot():
    """
    Shoot the portal gun
    """
    typer.echo("Shooting portal gun")


@app.command()
def load():
    """
    Load the portal gun
    """
    typer.echo("Loading portal gun")
```

!!! tip
    As we are creating an installable Python package, there's no need to add a section with `if __name__ == "__main__:`.

## Modify the README

Let's change the README. By default it's a file `README.rst`.

Let's change it to `README.md`. So, change the extension from `.rst` to `.md`.

So that we can use Markdown instead of reStructuredText.

And change the file to have something like:

```Markdown<commit_msg>✏ Fix syntax typo in `docs/tutorial/package.md` (#333)<commit_after>When you create a CLI program with **Typer** you probably want to create your own Python package.

That's what allows your users to install it and have it as an independent program that they can use in their terminal.

And that's also required for shell auto completion to work (unless you use your program through [Typer CLI](../typer-cli.md){.internal-link target=_blank}).

Nowadays, there are several ways and tools to create Python packages (what you install with `pip install something`).

You might even have your favorite already.

Here's a very opinionated, short guide, showing one of the alternative ways of creating a Python package with a **Typer** app, from scratch.

!!! tip
    If you already have a favorite way of creating Python packages, feel free to skip this.

## Prerequisites

For this guide we'll use <a href="https://python-poetry.org/" class="external-link" target="_blank">Poetry</a>.

Poetry's docs are great, so go ahead, check them and install it.

## Create a project

Let's say we want to create a CLI application called `portal-gun`.

To make sure your package doesn't collide with the package created by someone else, we'll name it with a prefix of your name.

So, if your name is Rick, we'll call it `rick-portal-gun`.

Create a project with Poetry:

<div class="termy">

```console
$ poetry new rick-portal-gun

Created package rick_portal_gun in rick-portal-gun

// Enter the new project directory
cd ./rick-portal-gun
```

</div>

## Dependencies and environment

Add `typer[all]` to your dependencies:

<div class="termy">

```console
$ poetry add typer[all]

// It creates a virtual environment for your project
Creating virtualenv rick-portal-gun-w31dJa0b-py3.6 in /home/rick/.cache/pypoetry/virtualenvs
Using version ^0.1.0 for typer

Updating dependencies
Resolving dependencies... (1.2s)

Writing lock file

---> 100%

Package operations: 15 installs, 0 updates, 0 removals

  - Installing zipp (3.1.0)
  - Installing importlib-metadata (1.5.0)
  - Installing pyparsing (2.4.6)
  - Installing six (1.14.0)
  - Installing attrs (19.3.0)
  - Installing click (7.1.1)
  - Installing colorama (0.4.3)
  - Installing more-itertools (8.2.0)
  - Installing packaging (20.3)
  - Installing pluggy (0.13.1)
  - Installing py (1.8.1)
  - Installing shellingham (1.3.2)
  - Installing wcwidth (0.1.8)
  - Installing pytest (5.4.1)
  - Installing typer (0.0.11)

// Activate that new virtual environment
$ poetry shell

Spawning shell within /home/rick/.cache/pypoetry/virtualenvs/rick-portal-gun-w31dJa0b-py3.6

// Open an editor using this new environment, for example VS Code
$ code ./
```

</div>

You can see that you have a generated project structure that looks like:

```
.
├── poetry.lock
├── pyproject.toml
├── README.rst
├── rick_portal_gun
│   └── __init__.py
└── tests
    ├── __init__.py
    └── test_rick_portal_gun.py
```

## Create your app

Now let's create an extremely simple **Typer** app.

Create a file `rick_portal_gun/main.py` with:

```Python
import typer


app = typer.Typer()


@app.callback()
def callback():
    """
    Awesome Portal Gun
    """


@app.command()
def shoot():
    """
    Shoot the portal gun
    """
    typer.echo("Shooting portal gun")


@app.command()
def load():
    """
    Load the portal gun
    """
    typer.echo("Loading portal gun")
```

!!! tip
    As we are creating an installable Python package, there's no need to add a section with `if __name__ == "__main__":`.

## Modify the README

Let's change the README. By default it's a file `README.rst`.

Let's change it to `README.md`. So, change the extension from `.rst` to `.md`.

So that we can use Markdown instead of reStructuredText.

And change the file to have something like:

```Markdown
{'fraction_non_alphanumeric': 0.11328228148930553, 'fraction_numerical': 0.01914444151043042, 'mean_word_length': 3.596480582524272, 'pattern_counts': {'":': 1, '<': 15, '<?xml version=': 0, '>': 17, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4004323', 'n_tokens_mistral': 2545, 'n_tokens_neox': 2459, 'n_words': 955}