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 hashes)

Uploaded source

Built Distribution

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

Uploaded py3

Supported by

AWS AWS Cloud computing Datadog Datadog Monitoring Facebook / Instagram Facebook / Instagram PSF Sponsor Fastly Fastly CDN Google Google Object Storage and Download Analytics Huawei Huawei PSF Sponsor Microsoft Microsoft PSF Sponsor NVIDIA NVIDIA PSF Sponsor Pingdom Pingdom Monitoring Salesforce Salesforce PSF Sponsor Sentry Sentry Error logging StatusPage StatusPage Status page