Skip to main content

A project cli command and config library

Project description

Ackermann - Command/Config Library

This library simplifies the startup process of a more complicated python project with multiple subcommands, a complicated configuration, aswell as certain targets that need to be run or initialized before starting commands in a specific order.

The point of this library is to easily provide a way to setup a commandline interface using logging and argparse and contextvars that looks like this:

my-programm -vvv -c <config_file.py> my-custom-command --my-custom-options

While providing a default way of starting the programm you might implemented way. Just have a look at ackermann.units. The main purpose of this library is just to provide an extentable way to implement commands and startup targets.

Usage

The most simple setup is just to call ackermann.run in your __main__ file, like so:

from ackermann import run
from ackermann.units import run_command

run(targets=[run_command])

Now if you execute your module with python -m <module> you can specify a config with -c change the verbosity level with -v and specify a subcommand.

Commands

If you want to write your own command you can do so:

from ackermann import Command, Config
from argparse import ArgumentParser
from time import sleep


class MyCommand(Command):
    name = "my-command"
    @classmethod
    def get_arguments(cls, parser: ArgumentParser):
        parser.add_argument("-s", "--skip", action="store_true")

    def run(self, config: Config):
        if config["ARGS"].skip:
            print("You wanted to skip")
        else:
            print("We are doing it as you are not skipping") 
            sleep(1000)

If you run your program as suggested you are able to run this command with:

python -m <project> my-command -s

The same works for async commands aswell:

from ackermann import Command, Config
from argparse import ArgumentParser
from asyncio import sleep


class MyAsyncCommand(Command):
    name = "my-async-command"
    is_async = True

    @classmethod
    def get_arguments(cls, parser: ArgumentParser):
        parser.add_argument("-s", "--skip", action="store_true")

    async def async_run(self, config: Config):
        if config["ARGS"].skip:
            print("You wanted to skip")
        else:
            print("We are doing it as you are not skipping") 
            await sleep(1000)

running this command would look like this:

python -m <project> my-async-command -s

Targets / Units

More complicated commands might want to reuse certain parts of code to initialize their project in the correct way. For this ackermann has ConfigUnits. These work pretty similiar to context managers around your command.

A unit might be defined like this:

from ackermann import Config, config_unit

@config_unit
async def do_sth(config: Config):
    print("I want to do sth before my command starts")
    yield
    print("Now I need to cleanup as the command finished")

This unit will not run by default, but it must be explicitly stated in the command. Using the targets variable. Config units might depend on each other, might conflict with one another or must be run in a certain order. They might also force the programm to be run in an async context or on multiple processors.

Signals

If your programm needs to signal certain parts of code about it's state you might also add signals. To your config by default before executing a command ackermann will signal ready and after exiting a command it will signal stopping. This might be used to signal systemd in case of using a notify service.

Config Variables

All commands, units and signals are called with the current instance of Config which itself stores configuration variables that might be stored in a python module supplied with the -c flag. If you want to explicitly tell the programm about these variables you can use the small wrapper ackermann.ConfigVar around contextvars.ContextVar which allows you to specify the format, type, and default value for a config variable.

These variables might then be imported in your programm without worrying where the get the correct value like so:

from ackermann import ConfigVar

config_my_config_var = ConfigVar("MY_CONFIG_VAR", description="Does something", type=int, default=0)

# At some point in the code

def do_sth():
    my_config_var_value = config_my_config_var.get()

One benefit of using this interface is that you can easily check the variables set when starting the programm with the -V flag.

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

ackermann-1.0.0.tar.gz (20.8 kB view details)

Uploaded Source

Built Distribution

ackermann-1.0.0-py3-none-any.whl (52.3 kB view details)

Uploaded Python 3

File details

Details for the file ackermann-1.0.0.tar.gz.

File metadata

  • Download URL: ackermann-1.0.0.tar.gz
  • Upload date:
  • Size: 20.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.0.1 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.0 CPython/3.9.5

File hashes

Hashes for ackermann-1.0.0.tar.gz
Algorithm Hash digest
SHA256 16da50d8d73975a999fa1751d80e20a2c3571adafc7b039d74ff5ba7a5f3dc46
MD5 02482b33474ff17eb9092948cde7ac1f
BLAKE2b-256 7786ebcc5c5eed1b42ed3e66d018c942026370e69c69b355b19f92ba4574d623

See more details on using hashes here.

File details

Details for the file ackermann-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: ackermann-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 52.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.0.1 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.0 CPython/3.9.5

File hashes

Hashes for ackermann-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 82a48972dc828c204ce0aa8893c9a2fbc22e046e7b25069fbfa395bcbb0a1446
MD5 e234441cefb711b877e69e46a0732c43
BLAKE2b-256 52eb0638304ebae459f14a7d27585f2ae842580ea4d7c62e942986e2afbd987d

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