Skip to main content

Typeo

(Pronounced like the abbreviation of "typographical error")

Turn annotated functions into command line scripts with a single line of code, and keep all your documentation!

Uses type annotations on functions to parse command line arguments, and strips help strings from function documentation.

Basic Usage

Say we have a file say_hello.py that looks like:

def say_hello(name: str, friendliness: int):
    """Say hello with various degrees of friendliness

    Args:
        name:
            The name of the person to greet
        friendliness:
            The level of friendliness to greet them with
    """

    if friendliness == 0:
        print("hey.")
    elif friendliness == 1:
        print(f"Hi {name}")
    elif friendliness > 1:
        print(f"Hello {name}!")
    else:
        raise ValueError(
            "Friendliness level cannot be less than 0"
        )

This function can be run as a command line utility by just adding

from hermes.typeo import typeo


@typeo
def say_hello(name: str, friendliness: int = 1):
    """Say hello to someone with various degrees of friendliness

    Args:
        name:
            The name of the person to greet
        friendliness:
            The level of friendliness to greet them with
    """

    if friendliness == 0:
        print("hey.")
    elif friendliness == 1:
        print(f"Hi {name}")
    elif friendliness > 1:
        print(f"Hello {name}!")
    else:
        raise ValueError(
            "Friendliness level cannot be less than 0"
        )


if __name__ == "__main__":
    say_hello()

Now when we run from the command line:

$ python say_hello.py -h
usage: say_hello [-h] --name NAME [--friendliness FRIENDLINESS]

Say hello to someone with various degrees of friendliness

optional arguments:
  -h, --help            show this help message and exit
  --name NAME           The name of the person to greet (default: None)
  --friendliness FRIENDLINESS
                        The level of friendliness to greet them with (default: 1)

$ python say_hello.py --name Thom
Hi Thom

$ python say_hello.py --name Thom --friendliness 2
Hello Thom!

$ python say_hello.py --friendliness 0
usage: say_hello [-h] --name NAME [--friendliness FRIENDLINESS]
say_hello: error: the following arguments are required: --name

Note that we can still import say_hello in other scripts and call it with regular arguments, and its behavior won't be impacted. typeo works by only reading from the command line if no arguments are passed in.

from say_hello import say_hello


# prints "Hi Thom"
say_hello("Thom", 1)

Note also that we can drop the if __name__ == "__main__" syntax if we integrate with Poetry package scripts. For example, if my pyproject.toml in the directory where I host say_hello.py has a section like:

[tool.poetry.scripts]
greet = "say_hello:say_hello"

Then I can drop the if __name__ == "__main__" from say_hello.py and run my script like this

$ poetry run greet --name Thom
Hi Thom

Subcommands

We can also add subcommands to our scripts. Let's say greet.py looks like

from hermes.typeo import typeo


def validate_friendliness(friendliness: int):
    if friendliness < 0:
        raise ValueError(
            "Friendliness level cannot be less than 0"
        )


def say_goodbye(name: str, friendliness: int = 1):
    """Say goodbye to someone with various degrees of friendliness

    Args:
        name:
            The name of the person to bid farewell
        friendliness:
            The level of friendliness to bid them farewell with
    """

    validate_friendliness(friendliness)

    if friendliness == 0:
        print("bye.")
    elif friendliness == 1:
        print(f"Goodbye {name}")
    else:
        print(f"So long {name}!")


def say_hello(name: str, friendliness: int = 1):
    """Say hello to someone with various degrees of friendliness

    Args:
        name:
            The name of the person to greet
        friendliness:
            The level of friendliness to greet them with
    """

    validate_friendliness(friendliness)
    if friendliness == 0:
        print("hey.")
    elif friendliness == 1:
        print(f"Hi {name}")
    else:
        print(f"Hello {name}!")


@typeo(hello=say_hello, goodbye=say_goodbye)
def greet(greeter: str):
    print(f"This is a greeting from {greeter}:")


if __name__ == "__main__":
    greet()
$ python greet.py -h
usage: greet [-h] --greeter GREETER {hello,goodbye} ...

positional arguments:
  {hello,goodbye}

optional arguments:
  -h, --help         show this help message and exit
  --greeter GREETER

$ python greet.py hello -h
usage: greet hello [-h] --name NAME [--friendliness FRIENDLINESS]

Say hello to someone with various degrees of friendliness



optional arguments:
  -h, --help            show this help message and exit
  --name NAME           The name of the person to greet (default: None)
  --friendliness FRIENDLINESS
                        The level of friendliness to greet them with (default: 1)

$ python greet.py goodbye -h
usage: greet goodbye [-h] --name NAME [--friendliness FRIENDLINESS]

Say goodbye to someone with various degrees of friendliness



optional arguments:
  -h, --help            show this help message and exit
  --name NAME           The name of the person to bid farewell (default: None)
  --friendliness FRIENDLINESS
                        The level of friendliness to bid them farewell with (default: 1)

$ python greet.py --greeter Jonny hello --name Thom
This is a greeting from Jonny:
Hi Thom

$ python greet.py --greeter Phil goodbye --name Jonny --friendliness 2
This is a greeting from Phil:
So long Jonny!

Metadata

Release files for hermes.typeo 0.1.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for hermes.typeo 0.1.5
File Size Uploaded
hermes.typeo-0.1.5.tar.gz 14.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for hermes.typeo 0.1.5
File Interpreter ABI Platform
hermes.typeo-0.1.5-py3-none-any.whl Python 3 none any Details

Total release size: 27.4 kB

Release files / hermes.typeo-0.1.5.tar.gz

Download URL hermes.typeo-0.1.5.tar.gz
Size 14.1 kB
Tags Source
SHA-256 checksum
How to use checksums
8bd1d97a698c0e99a7d2a6b3b082c8b8290aea1bf0e6a44548752ca178a8c73e
BLAKE2b-256 checksum
How to use checksums
5910598b328eb9e7d6725de7039f8424a3a47519b7b1ac22878dff2cf60d1bb1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.2.0a2 CPython/3.8.10 Linux/5.10.16.3-microsoft-standard-WSL2

Release files / hermes.typeo-0.1.5-py3-none-any.whl

Download URL hermes.typeo-0.1.5-py3-none-any.whl
Size 13.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a1fff2eeb257fb6f4f4b4b397681f2eddee59a4b8b3dd275f0fd9dac38e3371b
BLAKE2b-256 checksum
How to use checksums
273bc46da534a29d72a39f917e37bfd7bfa79bca212b9a0a38eafb8dbbdb1e10
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.2.0a2 CPython/3.8.10 Linux/5.10.16.3-microsoft-standard-WSL2

Release history Release notifications | RSS feed

This release

0.1.5 This release

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page