Skip to main content

Utilities for running functions as scripts

Project description

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!

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hermes.typeo-0.1.5.tar.gz (14.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

hermes.typeo-0.1.5-py3-none-any.whl (13.3 kB view details)

Uploaded Python 3

File details

Details for the file hermes.typeo-0.1.5.tar.gz.

File metadata

  • Download URL: hermes.typeo-0.1.5.tar.gz
  • Upload date:
  • Size: 14.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.2.0a2 CPython/3.8.10 Linux/5.10.16.3-microsoft-standard-WSL2

File hashes

Hashes for hermes.typeo-0.1.5.tar.gz
Algorithm Hash digest
SHA256 8bd1d97a698c0e99a7d2a6b3b082c8b8290aea1bf0e6a44548752ca178a8c73e
MD5 e82174b944f14d722f0672ccdd3d2cdc
BLAKE2b-256 5910598b328eb9e7d6725de7039f8424a3a47519b7b1ac22878dff2cf60d1bb1

See more details on using hashes here.

File details

Details for the file hermes.typeo-0.1.5-py3-none-any.whl.

File metadata

  • Download URL: hermes.typeo-0.1.5-py3-none-any.whl
  • Upload date:
  • Size: 13.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.2.0a2 CPython/3.8.10 Linux/5.10.16.3-microsoft-standard-WSL2

File hashes

Hashes for hermes.typeo-0.1.5-py3-none-any.whl
Algorithm Hash digest
SHA256 a1fff2eeb257fb6f4f4b4b397681f2eddee59a4b8b3dd275f0fd9dac38e3371b
MD5 dc5e744824e3eb871d31be696b141e58
BLAKE2b-256 273bc46da534a29d72a39f917e37bfd7bfa79bca212b9a0a38eafb8dbbdb1e10

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page