Skip to main content

clipyarser

clipyarser is a simple, declarative and easy-testable command line argument parser. Inspired by Typer.

Simply decorate your normal python functions with @clipyarser.main or @clipyarser.subcommand and you have a fully working cli program. clipyarser parses the arguments from the console and calls the matching function with the right arguments.

Tutorial

Here we will create a small command line application with clipyarser.

Setup

Create a new directory and an empty main.py file.

In main.py import clipyarser:

from clipyarser import CLI

Create a CLI parser

To create a clipyarser parser, simply write this to your main.py file.

from clipyarser import Clipyarser

clipyarser = Clipyarser()

Now we create a simple greeting function.

@clipyarser.main
def main(name: str) -> str:
    return f'Hello {name}'

This function simply returns a string which says hello to a person. The name of the person is specified in the arguments of the function.

Note that we use type hints in the function arguments. This is necessary for clipyarser, because it parses the arguments from the console according to the specified types. So when adding an argument age with type int, clipyarser does the parsing and validation of an int for you.

Now, we have to execute clipyarser when the program is run.

if __name__ == '__main__':
    clipyarser.run()

And that is the first running example of clipyarser.

Now lets test it.

$ python3 main.py
usage: example.py [-h] name {} ...
example.py: error: the following arguments are required: name

Ok, we have to specify the name of the person we want to greet. This makes sense, because we take name as argument in our main() function.

$ python3 main.py Linus
Hello Linus

Ok nice. That worked.

Default Arguments/Options

Sometimes it is convenient that a function has default arguments, which can be overridden when calling the function. This is also possible with clipyarser. Let's try to take our greeting function from above and extend it with an optional argument.

@clipyarser.main
def main(name: str, greeting: str = 'Hello') -> str:
  return f'{greeting} {name}'

So a user can customize the greeting. By default, the greeting is 'Hello', but it can be overridden. Now let's see how this looks in the console.

$ python3 main.py Linus
Hello Linus
$ python3 main.py Linus --greeting Hi
Hi Linus

Pretty intiutive, right?

Subcommands

In a bigger application, you may don't want all logic in a main() function. Therefore, clipyarser allows you to add subcommands.

from clipyarser import Clipyarser

clipyarser = Clipyarser()

@clipyarser.subcommand
def add(a: int, b: int) -> int:
    return a + b

This subcommand is a function which adds to numbers together.

$ python3 main.py add 2 4
6

But what has happened to the main function? For simplicity, we have deleted it. Let's try to add one again.

@clipyarser.main
def main(verbose: bool = False):
  return 'verbose is {verbose}'

Now, when calling our application, the main() function always runs. This might be handy when you have some logic or arguments that are independent of am individual subcommand, like a more verbose output.

$ python3 main.py add 3 2
verbose is False
5
$ python3 main.py --verbose true add 3 2
verbose is True
5

Printing multiple lines

Until now when we want to print something to the console, we just returned it. This might seem ok, but sometimes you want to print multiple lines or want to print something during a calculation. But simple do print() is not a good idea. We will se soon why.

To print multiple lines, use the yield statement.

Back to our greeting example from the beginning.

from time import sleep
from clipyarser import Clipyarser

clipyarser = Clipyarser()


@clipyarser.main
def main(name: str):
    yield 'Hello'
    sleep(2)
    yield name
    yield 42
$ python3 main.py Linus
Hello
Linus
42

Because yield turns main() into a generator function, the output 'Hello' is printed immediately, but name takes two seconds to print.

Maybe one could think of another solution: Just add all things to be printed to a list and return this list at the end of the function. This is bad, because the whole output takes two seconds to print, in particular the 'Hello' line. This makes your clipyarser not very responsive to the end user.

Ok. But why is just printing a bad idea? Testing.

Testing

The advantage of CLI is simple testing. Functions like main() and add() are normal python functions, so you can call them like normal functions. They take normal arguments. They return normal things. This means that you can also test these functions like normal functions.

import unittest
from clipyarser import Clipyarser

clipyarser = Clipyarser()


class TestMyCli(unittest.TestCase):
    def test_greet(self):
        actual = list(main('Linus'))
        expected = ['Hello', 'Linus', 42]
        self.assertEqual(actual, expected)

Since main() is a generator function, we can convert its output to a list and check if it is what we expect. If using print(), this would not be as easy.

Ok, this is the end of the tutorial. Have fun using clipyarser.

Release files for clipyarser 0.2.0

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

Source distribution (sdist)

Source distribution for clipyarser 0.2.0
File Size Uploaded
clipyarser-0.2.0.tar.gz 5.9 kB Details

Built distribution (wheel)

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

Total release size: 11.5 kB

Release files / clipyarser-0.2.0.tar.gz

Download URL clipyarser-0.2.0.tar.gz
Size 5.9 kB
Tags Source
SHA-256 checksum
How to use checksums
78892e748c868112e0097e7bda7144e016eba62445662dae31b02dd7604775d5
BLAKE2b-256 checksum
How to use checksums
370c08d71f10acff580cddd67e196c53d78fe8954ffc04b3598933681e5ebb53
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.1.13 CPython/3.8.10 Linux/5.15.0-48-generic

Release files / clipyarser-0.2.0-py3-none-any.whl

Download URL clipyarser-0.2.0-py3-none-any.whl
Size 5.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2cafea213da52b019cd8ec8c2b9a20b02a5188618ab400022bb857fe8250ed12
BLAKE2b-256 checksum
How to use checksums
687fd5d7b22f9bd307393387febf9e602bf94c10008570c51062ac6db81607fd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.1.13 CPython/3.8.10 Linux/5.15.0-48-generic

Release history Release notifications | RSS feed

This release

0.2.0 This release

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