Skip to main content

Barim is a Python library that helps building CLI applications

Project description

Barim

python pipeline - passed version alpha - 0.1.0 license - MIT code style - black coverage - unknown

Barim is a Python library that helps building CLI applications.

The Barim API makes it easy to build terminal app that have one or more commands.

Requirements

Dev requirements

Installing

Install with pip.

python -m pip install barim

Install with poetry.

poetry add barim

Quickstart

This following section is dedicated to explain how barim can be used to create a simple CLI application. We will see how to make a terminal application with a default command and how we can update it to allow multiple subcommand.

Create your first command

The first step will be to create a class that inherit from barim.Command and provide some values to the class attributes.

# File name: example.py
from types import SimpleNamespace

from barim import Command


class MyCommand(Command):
    
    name = "example.py"
    description = "Print 'Hello, World!'"
    version = "0.1.0"

    def handle(self, argv: SimpleNamespace, opts: SimpleNamespace) -> None:
        print("Hello, World!")

Take note that the class attributes 'description' and 'version' aren't mandatory. Only 'name' is.

The handle() method must be override has it will be the entry point for your software. The argv and opts parameters are two SimpleNamespace that contain all the arguments (argv) and all the options (opts) declared in the command class. To see how to use them check out the Barim API or just continue the quickstart guide.

The next logical step now is just to tell barim to run the command when the script is run. This can be done like the following.

from types import SimpleNamespace

from barim import Application, Command


class MyCommand(Command):
    
    name = "my_command"
    description = "Print 'Hello, World!'"
    version = "0.1.0"

    def handle(self, argv: SimpleNamespace, opts: SimpleNamespace) -> None:
        print("Hello, World!")

        
# Notice we add a main method to be called once the script is runned        
def main() -> None:
    application = Application(name="example.py")
    application.register(MyCommand)
    application.run(default=True)


if __name__ == "__main__":
    main()

That should be all ! You can now test your CLI application by running the following command.

python example.py --help

The output of the command should be:

example.py version 0.1.0

DESCRIPTION
    Print 'Hello, World!'

USAGE
    example.py  [-h] [-V] [-v]

GLOBAL OPTIONS
    -h (--help)             Display help message
    -V (--version)          Display version number
    -v (--verbose)          Display more log message

Something to notice here is that the output doesn't show any colors (in this README) which will not be the case on the terminal.

Add arguments and options to the command

Let's say now that we want to take a string as an argument to print 'Hello, {input}!'. For this we need to declare another class variable named 'arguments' that is a list of barim.Argument.

from types import SimpleNamespace

from barim import Application, Argument, Command


class MyCommand(Command):
    name = "my_command"
    description = "Print 'Hello, {input}!'"
    version = "0.1.0"

    arguments = [
        Argument(
            name="input",
            description="Use input string in print statement"
        ),
    ]

    def handle(self, argv: SimpleNamespace, opts: SimpleNamespace) -> None:
        # Make use of the newly added argument
        print(f"Hello, {argv.input}")


def main() -> None:
    application = Application(name="example.py")
    application.register(MyCommand)
    application.run(default=True)


if __name__ == "__main__":
    main()

Note that you can declare a barim.Argument or by providing the needed data during initialization like in the example above or by subclassing it and declaring the data as class variable.

You should now be able to run your script like the following.

python example.py Demo

Expected output:

Hello, Demo!

Now when it comes to options, it doesn't change that much. Instead of declaring arguments you declare options and provide a list of barim.Option. In our example let's say we want to turn all the letter uppercase.

from types import SimpleNamespace

from barim import Application, Argument, Command, Option


class MyCommand(Command):
    name = "my_command"
    description = "Print 'Hello, {input}!'"
    version = "0.1.0"

    arguments = [
        Argument(
            name="input",
            description="Use input string in print statement"
        ),
    ]
    options = [
        Option(
            short="u",
            long="upper",
            description="Turn all the letter uppercase",
        ),
    ]

    def handle(self, argv: SimpleNamespace, opts: SimpleNamespace) -> None:
        # Make use of newly added option
        input_ = argv.input
        if opts.upper:
            input_ = input_.upper()

        print(f"Hello, {input_}")


def main() -> None:
    application = Application(name="example.py")
    application.register(MyCommand)
    application.run(default=True)


if __name__ == "__main__":
    main()

Now run your script as below.

python example.py demo --upper

Expected output:

Hello, DEMO!

Create subcommands

The default parameter declare earlier in application.run(default=True) indicate that we only have one registered command and that we want to use it as the default one. By removing this parameter we can now register multiple command to act as multiple sub command.

from types import SimpleNamespace

from barim import Application, Argument, Command, Option


class MyCommand(Command):
    name = "my_command"
    description = "Print 'Hello, {input}!'"
    version = "0.1.0"

    arguments = [
        Argument(
            name="input",
            description="Use input string in print statement"
        ),
    ]
    options = [
        Option(
            short="u",
            long="upper",
            description="Turn all the letter uppercase",
        ),
    ]

    def handle(self, argv: SimpleNamespace, opts: SimpleNamespace) -> None:
        input_ = argv.input
        if opts.upper:
            input_ = input_.upper()

        print(f"Hello, {input_}")


class MyOtherCommand(Command):
    name = "my_other_command"
    description = "Print 'Hello, World!'"
    version = "0.1.0"
    
    def handle(self, argv: SimpleNamespace, opts: SimpleNamespace) -> None:
        print("Hello, World")
        
        
def main() -> None:
    application = Application(name="example.py")
    application.register(MyCommand)
    application.register(MyOtherCommand)
    application.run()


if __name__ == "__main__":
    main()

Create command dynamically

As seen before, to create a command, we have to subclass barim.Command. But this is not the only way we can create them. In any case you need to create them, for example on the fly, you could do it like in the following example.

from types import SimpleNamespace

from barim import Application, Command


def my_command_handle(argv: SimpleNamespace, opts: SimpleNamespace) -> None:
    print("Hello, World")

    
def main() -> None:
    my_command = Command(name="my_command", description="Print 'Hello, World!'", handle=my_command_handle)
    
    application = Application(name="example.py")
    application.register(my_command)
    application.run(default=True)

    
if __name__ == "__main__":
    main()

The output of the command should look like the following:

example.py version 0.1.0

DESCRIPTION
    Print 'Hello, World!'

USAGE
    example.py  [-h] [-V] [-v]

GLOBAL OPTIONS
    -h (--help)             Display help message
    -V (--version)          Display version number
    -v (--verbose)          Display more log message

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

barim-0.1.0.tar.gz (10.9 kB view details)

Uploaded Source

Built Distribution

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

barim-0.1.0-py3-none-any.whl (8.7 kB view details)

Uploaded Python 3

File details

Details for the file barim-0.1.0.tar.gz.

File metadata

  • Download URL: barim-0.1.0.tar.gz
  • Upload date:
  • Size: 10.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.13 CPython/3.9.2 Linux/5.10.0-14-amd64

File hashes

Hashes for barim-0.1.0.tar.gz
Algorithm Hash digest
SHA256 e198b34d66e33c8c1cb9ae825750d5b39923e6ac6dae7167f9da80af1918f1c1
MD5 a9c6516ca63bbb0f3392951478e986ee
BLAKE2b-256 23f86d99862b2b1f686b980b29e684d0ff242a18b274e67c20f93a6fc006667a

See more details on using hashes here.

File details

Details for the file barim-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: barim-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 8.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.13 CPython/3.9.2 Linux/5.10.0-14-amd64

File hashes

Hashes for barim-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e4e66188cb4869f27bbe19b84a5d9f4ca832a17e7628a92a0ddf6a00a88d5391
MD5 7a80a695c3a8b313da66ab347ceccf23
BLAKE2b-256 1c46d05679b453e242da2ee0d27e4bebdc935580a3ea71a529ffec8232a01570

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