Skip to main content

a lightweight framework for creating command line interfaces quickly

Project description

cliq: creating command line interfaces quickly in Python

cliq is a lightweight framework for creating a command line application or writing a libary powered with command line tools in Python.

  • supports nested subcommands
  • equiped with init and config system
  • supports multiple command line tools in a single library
  • only depends on the standard library

Quick Start

Install cliq:

$ pip install cliq

Create your project:

$ cliq create project ./myapp
$ pip install -e ./myapp
$ myapp

Create a new command:

$ cliq create command do.py
$ python do.py -h

Add the command to your project:

$ mv do.py ./myapp/myapp/main/command/
$ myapp do -h

Remove help, init, config commands if you don't need them:

$ cd ./myapp/myapp/main/command
$ rm help.py init.py config.py

Commands

  • A command is standalone and complete by itself if you don't need config.
  • You can run it as an independent script.
  • Just copy a command script into your project.
  • There is nothing to be configured.

Try toy sample commands:

$ cliq create project myapp --sample
$ pip install -e ./myapp 
$ myapp say hello
hello
$ cliq please say hello
hello
$ cliq please sum 1 2 3 4 5
15.0

Write your command:

  • It's just an argparse.ArgumentParser
  • See https://docs.python.org/3/library/argparse.html
  • Add arguments to the self.parser
  • Write the run method
  • Your command runs standalone if you don't use the app variable, which allows your command to access config variables through app.config.

Create a command script:

$ cliq create command say.py 

Edit the script:

...

class Command(SimpleCommand):
    def __init__(self, app = None, name = __name__):
        super().__init__(app, name)

        # self.parser is an argparse.ArumentParser
        # see https://docs.python.org/3/library/argparse.html       
        #
        # add arguments. for example:
        #
        # self.parser.add_argument('input', type=str, help='input filename')
        # self.parser.add_argument('-v', '--verbose', action='store_true', help='verbose')
        # self.parser.add_argument('-o', '--output', type=str, help='output filename')

    def run(self, argv):
        args = self.parser.parse_args(argv)

        # implement command line functionalities
        print(args)
 
...

Library

Create a project and add modules:

$ cliq create project mylib
$ pip install -e ./mylib
$ echo 'def mean(*x): return sum(x)/len(x)' > mylib/mylib/math.py

It is a normal library:

>>> import mylib.math
>>> mylib.math.mean(1, 2, 3, 4, 5)
3.0

Add commands. For example,

$ cliq create command mylib/mylib/main/command/mean.py
import sys
from cliq.main.command import SimpleCommand
import mylib.math

def init(app):
    return Command(app)

class Command(SimpleCommand):
    def __init__(self, app = None, name = __name__):
        super().__init__(app, name)

        self.parser.add_argument('x', type=float, nargs='+')

    def run(self, argv):
        args = self.parser.parse_args(argv)

        # implement command line functionalities
        print(mylib.math.mean(*args.x))
 

Run the command:

$ mylib mean 1 2 3 4
2.5

Tutorial

Concepts

app, command and subcommand

cliq supports nested command line interfaces to the depth 3: app, command, and subcommand.

$ cliq   create     project       ./myapp      --with-sample-commands
$ pip    install                               -e ./myapp
$ myapp  please     sum           1 2 3 
$ myapp  say                      hello
$ myapp                                        --help
  <app>  <command>  <subcommand>  <arguments>  <options>

project, library and app

cliq supports a library with multiple command line apps:

$ cliq create project ./myproj --name mylib --cli myapp,yourapp
$ pip install -e ./mylib
$ myapp -h
$ yourapp -h

See the directory structure: project, library and apps.

$ tree myproj
myproj
├── README.md
├── mylib
│   ├── __init__.py
│   ├── myapp
│   │   ├── __init__.py
│   │   └── main
│   │       ├── __init__.py
│   │       └── command
│   │           ├── config.py
│   │           ├── help.py
│   │           └── init.py
│   └── yourapp
│       ├── __init__.py
│       └── main
│           ├── __init__.py
│           └── command
│               ├── config.py
│               ├── help.py
│               └── init.py
├── setup.cfg
└── setup.py

7 directories, 14 files

Simple command

Generate a simple command template script file:

$ cliq create command say.py  
$ python say.py -h
usage: __main__ [-h]

options:
  -h, --help  show this help message and exit

Add arguments to self.parser and implement run method:

class Command(SimpleCommand):
    def __init__(self, app = None, name = __name__):
        super().__init__(app, name)
        
        self.parser.add_argument('something', type=str, help='something')
        
    def run(self, argv):
        args = self.parser.parse_args(argv)
        print(args.something)

Use it:

$ python say.py hello
hello

Complex command with nested subcommands

Create a command script file with the subcommands option:

$ cliq create command do.py --with-subcommands something,anything,nothing 

Test it:

$ python do.py
usage: __main__ [-h] {something,anything,nothing} ...

options:
  -h, --help            show this help message and exit

subcommands:
  {something,anything,nothing}
                        command help
    something           something
    anything            anything
    nothing             nothing

Edit it and put it into the command directory:

$ mv do.py myapp/myapp/main/command/

Project with multiple command line modules

You can create a project with multiple command line interface modules.

$ cliq create project ./holy --with-cli graham,terry 
$ pip install -e ./holy

Directory strucutre:

holy/
└── holy
    ├── graham
    │   └── main
    │       └── command
    └── terry
        └── main
            └── command

Test cli modules:

$ graham -h 
...

$ terry -h 
...

Add commands:

$ cliq create command holy/holy/graham/main/command/say.py
$ graham say -h

$ cliq create command holy/holy/graham/main/command/play.py --sub role,instrument
$ graham play role -h
$ graham play instrument -h

Simple command line apps

A command line module can run without predefined commands. Just put your command script named __init__.py into the path <app>/main/command/.

myapp/
├── __init__.py
└── main
    ├── __init__.py
    └── command
        └── __init__.py

For example, you are going to write a image library with command line converters.

$ cliq create project myimglib --cli png2jpg,jpg2png
$ pip install -e ./myimglib/
$ cliq create command myimglib/myimglib/png2jpg/main/command/__init__.py
$ png2jpg --help

Open __init__.py and write your code. png2jpg runs the code in __init__.py. Remove default command scripts if you don't need them.

$ rm myimglib/myimglib/png2jpg/main/command/*
$ cliq create command myimglib/myimglib/png2jpg/main/command/__init__.py

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

cliq-0.9.3.tar.gz (15.8 kB view details)

Uploaded Source

Built Distribution

cliq-0.9.3-py2.py3-none-any.whl (20.5 kB view details)

Uploaded Python 2 Python 3

File details

Details for the file cliq-0.9.3.tar.gz.

File metadata

  • Download URL: cliq-0.9.3.tar.gz
  • Upload date:
  • Size: 15.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.8.0 pkginfo/1.8.2 readme-renderer/32.0 requests/2.27.1 requests-toolbelt/0.9.1 urllib3/1.26.8 tqdm/4.62.3 importlib-metadata/4.11.1 keyring/23.5.0 rfc3986/2.0.0 colorama/0.4.4 CPython/3.10.1

File hashes

Hashes for cliq-0.9.3.tar.gz
Algorithm Hash digest
SHA256 c6606e8d0304c85e84f43e97bdef694bcd5580a1a897614784e483b7e007aa2d
MD5 01864e9a06cddd0d795b402482efbc0a
BLAKE2b-256 c1153808d1340c840f1c447556b43fbb96612f7193db8b3e348eb034d85210dd

See more details on using hashes here.

File details

Details for the file cliq-0.9.3-py2.py3-none-any.whl.

File metadata

  • Download URL: cliq-0.9.3-py2.py3-none-any.whl
  • Upload date:
  • Size: 20.5 kB
  • Tags: Python 2, Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.8.0 pkginfo/1.8.2 readme-renderer/32.0 requests/2.27.1 requests-toolbelt/0.9.1 urllib3/1.26.8 tqdm/4.62.3 importlib-metadata/4.11.1 keyring/23.5.0 rfc3986/2.0.0 colorama/0.4.4 CPython/3.10.1

File hashes

Hashes for cliq-0.9.3-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 a244d0bda0f10cb5a39b24a6007d3697fcf56ef967773bb261451cd312d7b618
MD5 5e81d7354a777f18faf48bb1c9b15ca0
BLAKE2b-256 785c2eeb3c38b1116d328b05ec57df62d10df28b17fd5c33521a9ad43ea6c17d

See more details on using hashes here.

Supported by

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