Skip to main content

Python cli scripts for humans

Project description

Captain

Easy python CLI scripts for people that just want get things done.

Usage

A valid captain CLI script needs just two things:

  1. A Default class that extends captain.Command and has a handle() method (can be async):

    from captain import Command
    
    class Default(Command):
        async def handle(self, foo, bar):
            return 0
    
  2. Calling captain.application() at the end of your script:

    from captain import Command, application
    
    class Default(Command):
        async def handle(self, foo, bar):
            return 0
    
    if __name__ == "__main__":
        application()
    

That's it! Whatever arguments you define in your class's Default.handle() method will be options on the command line. A captain script is called just like any other python command line script, so to run the above example you could do:

$ python path/to/script.py --foo=1 --bar=2

Argument Decorator

The captain.arg() decorator provides a nice passthrough api to the full argparse.ArgumentParser.add_argument() method if you want to fine tune how arguments are passed into your script:

from captain import Command, application, arg

class Default(Command):
    @arg('--foo', '-f', action="store_true")
    @arg('arg', metavar='ARG')
    async def handle(self, *args, **kwargs):
        '''this is the help description'''
        self.output.out(args)
        self.output.out(kwargs)

if __name__ == "__main__":
    application()

Would print a help string like this:

usage: script.py [-h] [--foo FOO] ARG

this is the help description

positional arguments:
  ARG

optional arguments:
  -h, --help         show this help message and exit
  --foo FOO, -f FOO

Command Output

The captain.io.Output class makes it easy to print stuff in your script while still giving you full control by being able to configure the logger if you need to. It also will obey the global --quiet flag that Captain adds to every script.

It's available in the handle() method by using self.output:

from captain import Command

class Default(Command):
    async def handle(self, *args, **kwargs):
        var1 = "print"

        var2 = "stdout"
        self.output.out("this will {} to {}", var1, var2)

        var2 = "stderr"
        self.output.err("this will {} to {}", var1, var2)

        e = ValueError("this will print with stacktrace and everything")
        self.output.exception(e)

The captain.io.Output class has a lot of nice little helper methods but Captain can also work with modules like clint if you need to do more advanced cli output.

Examples

A typical python cli script

import argparse

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='fancy script description')
    parser.add_argument("--foo", action='store_true')
    parser.add_argument("--bar", default=0, type=int)
    parser.add_argument("args", nargs='*')
    args = parser.parse_args()
    sys.exit(0)

would become:

import captain

class Default(captain.Command):
    async def handle(self, *args, foo: bool = False, bar:int = 0):
        """fancy script description"""
        return 0

if __name__ == '__main__':
    captain.application()

Subcommands

Captain supports multiple subcommands defined in the script by naming your captain.Command child classes something other than Default:

# cli.py

import captain

class Foo(captain.Command):
    async def handle(self):
        self.output.out("Foo called")

class Bar(captain.Command):
    async def handle(self):
        self.output.out("Bar called")

if __name__ == '__main__':
    captain.application()

So foo could be called using:

$ python cli.py foo
Foo called

And bar could be called using:

$ python cli.py bar
Bar called

Embedding captain in another package

If you want a script from you package to be usable using both python -m example and maybe a console_scripts entry point defined in setup.py, you can set up your package's __main__.py module like this:

# example/__main__.py

from captain import Command, application

class Default(captain.Command):
    async def handle(self):
        pass
        
if __name__ == "__main__":
    application()

And then in your setup.py script you can add:

entry_points = {
    'console_scripts': [
        'example = example.__main__:application'
    ],
}

That's all there is to it.

Install

Use pip:

$ pip install captain

For latest and greatest:

$ pip install -U "git+https://github.com/Jaymon/captain#egg=captain"

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

captain-6.1.0.tar.gz (30.7 kB view details)

Uploaded Source

Built Distribution

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

captain-6.1.0-py3-none-any.whl (32.7 kB view details)

Uploaded Python 3

File details

Details for the file captain-6.1.0.tar.gz.

File metadata

  • Download URL: captain-6.1.0.tar.gz
  • Upload date:
  • Size: 30.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.11

File hashes

Hashes for captain-6.1.0.tar.gz
Algorithm Hash digest
SHA256 e4eafef39779c964144bb7256350c3704f76e646cddd890bd84ece03aeb59a5e
MD5 bc07bb4fdf8bff575dcfca559769d98e
BLAKE2b-256 1a5a6503f362c63a0ce4744d2c327ba92a2911288af0a5d3a2d79f3a05ea3ea5

See more details on using hashes here.

File details

Details for the file captain-6.1.0-py3-none-any.whl.

File metadata

  • Download URL: captain-6.1.0-py3-none-any.whl
  • Upload date:
  • Size: 32.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.11

File hashes

Hashes for captain-6.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5b50cb32302d6cea056143ed92b9347d33ec47f69621bc2da4d6521bd5b2f863
MD5 d1708a4413b98da14a1b9fda972af7da
BLAKE2b-256 19f5254ec07e7498d33aef4d469f74786ae8872ba6992a1f9ebeb947d98709aa

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