Registering CLI Commands in Cellframe Node

The node.cli module provides classes for registering CLI (Command Line Interface) commands in the Cellframe Node. This example demonstrates how to register and handle CLI commands using this module.

Overview

In this example, we will:

  1. Define functions to process command-line arguments.
  2. Use the OptionParser from the optparse Python module to handle command-line options.
  3. Register CLI commands using the AppCliServer.cmdItemCreate method.
  4. Log the results of command execution.

Command Handlers

We define two command handlers:

  • command_sum: Adds two numbers passed from the command line.
  • hash_callback: Checks for a hash presence in a dictionary and returns its keys depending on the provided options.

Initialization

For direct registration, use following sighnature in the init() function:

AppCliServer.cmdItemCreate(
    "name_of_the_command",
    name_of_the_handler_func,
    "description",
    "help text"
)

Below is an example for registering two commands with options:

from optparse import OptionParser
from DAP.Core import logIt
from CellFrame import AppCliServer
 
 
# Create a simple command handler, which sums numbers from the command prompt
def command_sum(args, reply_index):
    logIt.debug(f"command sum called with args: {args}")
 
    # Create an option parser to handle command line options,
    # specifically adding a verbose mode option
    parser = OptionParser()
    parser.add_option("-v",
                      "--verbose",
                      action="store_true",
                      dest="verbose",
                      help="Enable verbose output")
 
    # Parse the arguments, skip the first argument which is the command name
    options, arguments = parser.parse_args(args[1:])
 
    try:
        # Convert all arguments to integers and sum them up
        numbers = [int(arg) for arg in arguments]
        result = sum(numbers)
 
        # Process the logic in the case when the command
        # is called with and without option.
        if options.verbose:
            result_message = "Verbose message: Command executed successfully."
            result_message += f"\nThe result of the execution is {result}."
            reply = result_message
        else:
            reply = f"Command executed successfully.\n{result}"
    except ValueError:
        # Handle the case where arguments cannot be converted to integers
        reply = "All arguments must be integers."
 
    # Set the reply text for the CLI
    AppCliServer.setReplyText(reply, reply_index)
 
# Create a more complex command handler.
# Let the function check for a hash in the dictionary and
# return its keys depending on the options provided.
 
 
hsh_dict = {
    "hash1": {"nonce": 123, "gas": 10000},
    "hash2": {"nonce": 456, "gas": 20000},
}
 
 
def hash_callback(args, reply_index):
    logIt.debug(f"hash_callback called with args: {args}")
 
    # Create an option parser to handle command line options,
    # specifically adding nonce and gas options
    parser = OptionParser()
    parser.add_option("-n",
                      "--nonce",
                      action="store_true",
                      dest="nonce",
                      help="Include nonce in the output")
    parser.add_option("-g",
                      "--gas",
                      action="store_true",
                      dest="gas",
                      help="Include gas in the output")
 
    # Parse the arguments
    options, arguments = parser.parse_args(args[1:])
 
    # Check if a hash was provided
    if not arguments:
        reply = "No hash provided."
        AppCliServer.setReplyText(reply, reply_index)
        return
 
    hsh = arguments[0]
 
    # Process the logic based on the provided hash and options
    if hsh in hsh_dict:
        nonce_value = hsh_dict[hsh]["nonce"]
        gas_value = hsh_dict[hsh]["gas"]
 
        if options.nonce and options.gas:
            reply = f"Hash {hsh} found. Nonce: {nonce_value}, Gas: {gas_value}"
        elif options.nonce:
            reply = f"Hash {hsh} found. Nonce: {nonce_value}"
        elif options.gas:
            reply = f"Hash {hsh} found. Gas: {gas_value}"
        else:
            reply = f"Hash {hsh} found."
    else:
        reply = f"Hash {hsh} not found in the dictionary."
 
    # Set the reply text for the CLI
    AppCliServer.setReplyText(reply, reply_index)
 
 
def init():
    # Creating CLI command "sum"
    AppCliServer.cmdItemCreate(
        "sum",
        command_sum,
        "Sum command",
        "This command sums up all the numbers passed to it."
    )
 
    # Creating CLI command "hash_check"
    AppCliServer.cmdItemCreate(
        "hash_check",
        hash_callback,
        "Hash check command",
        (
            "This command checks for a hash in the dictionary and "
            "optionally includes nonce and gas in the output."
        )
    )
    return 0
 

To call commands, use cellframe-node-cli utility by following: cellframe-node-cli my_command 1 2, or use 1. Introduction client.