Common CLI Modules
This module includes common CLI methods and parser extension
Attributes
BOLD module-attribute
BOLD = '\x1b[1m'
GRN module-attribute
GRN = '\x1b[1;32m'
NC module-attribute
NC = '\x1b[0m'
RED module-attribute
RED = '\x1b[1;31m'
YLW module-attribute
YLW = '\x1b[1;33m'
Classes
CLIArgumentParser
CLIArgumentParser(subparser, parser=None)
Source code in fedbiomed/common/cli.py
def __init__(self, subparser: argparse.ArgumentParser, parser = None):
self._subparser = subparser
# Parser that is going to be add using subparser
self._parser = None
self._main_parser = parser
Functions
default
default(args=None)
Default function for subparser command
Source code in fedbiomed/common/cli.py
def default(self, args: argparse.Namespace = None) -> None:
"""Default function for subparser command"""
self._parser.print_help()
return None
CommonCLI
CommonCLI()
Source code in fedbiomed/common/cli.py
def __init__(self) -> None:
self._parser: argparse.ArgumentParser = argparse.ArgumentParser(
prog="fedbiomed", formatter_class=argparse.RawTextHelpFormatter
)
self._subparsers = self._parser.add_subparsers()
self._certificate_manager: CertificateManager = CertificateManager()
self._description: str = ""
self._args = None
Attributes
arguments property
arguments
config instance-attribute
config
description property
writable
description
parser property
parser
subparsers property
subparsers
Gets subparsers of common cli
Returns:
Type | Description |
---|---|
Subparsers of CLI parser |
Functions
config_action staticmethod
config_action(this, component)
Returns CLI argument action for config file name
Source code in fedbiomed/common/cli.py
@staticmethod
def config_action(this: "CommonCLI", component: ComponentType):
"""Returns CLI argument action for config file name"""
return ComponentDirectoryAction
error staticmethod
error(message)
Prints given error message
Parameters:
Name | Type | Description | Default |
---|---|---|---|
message | str | Error message | required |
Source code in fedbiomed/common/cli.py
@staticmethod
def error(message: str) -> None:
"""Prints given error message
Args:
message: Error message
"""
print(f"{RED}ERROR:{NC}")
print(f"{BOLD}{message}{NC}")
logger.critical(message)
sys.exit(1)
initialize
initialize()
Initializes parser classes and common parser for child classes.
This parser classes will be added by child classes.
Source code in fedbiomed/common/cli.py
def initialize(self):
"""Initializes parser classes and common parser for child classes.
This parser classes will be added by child classes.
"""
self._parser.add_argument(
"-y",
action="store_true"
)
for arg_parser in self._arg_parsers_classes:
p = arg_parser(self._subparsers, self._parser)
p.initialize()
self._arg_parsers.update({arg_parser.__name__: p})
self.initialize_certificate_parser()
initialize_certificate_parser
initialize_certificate_parser()
Common arguments
Source code in fedbiomed/common/cli.py
def initialize_certificate_parser(self):
"""Common arguments"""
# Add certificate sub parser (sub-command)
certificate_parser = self._subparsers.add_parser(
"certificate",
help="Command to manage certificates in node and researcher components. "
"Please see 'certificate --help' for more information.",
prog="fedbiomed [ node | researcher ] [--path [COMPONENT_DIRECTORY]] certificate",
)
def print_help(args):
certificate_parser.print_help()
certificate_parser.set_defaults(func=print_help)
# Create sub parser under `certificate` command
certificate_sub_parsers = certificate_parser.add_subparsers(
description="Commands that can be used with the option `certificate`",
title="Subcommands",
)
register_parser = certificate_sub_parsers.add_parser(
"register",
help="Register certificate of specified party. Please run 'fedbiomed' "
"[COMPONENT SPECIFICATION] certificate register --help'",
) # command register
list_parser = certificate_sub_parsers.add_parser(
"list", help="Lists registered certificates"
) # command list
delete_parser = certificate_sub_parsers.add_parser(
"delete", help="Deletes specified certificate from database"
) # command delete
# Command `certificate generate`
generate = certificate_sub_parsers.add_parser(
"generate",
help="Generates certificate for given component/party if files don't exist yet. "
"Uses an alternate directory if '--path DIRECTORY' is given."
" If files already exist, overwrite existing certificate.\n"
"Certificate are here refering to the public certificate and its associated private key "
"(the latter should remain secret and not shared to other parties)."
)
# Command `certificate generate`
prepare = certificate_sub_parsers.add_parser(
"registration-instructions",
help="Prepares certificate of current component to send other FL participant"
" through trusted channel.",
)
register_parser.set_defaults(func=self._register_certificate)
list_parser.set_defaults(func=self._list_certificates)
delete_parser.set_defaults(func=self._delete_certificate)
generate.set_defaults(func=self._generate_certificate)
prepare.set_defaults(func=self._prepare_certificate_for_registration)
# Add arguments
register_parser.add_argument(
"-pk",
"--public-key",
metavar="PUBLIC_KEY",
type=str,
nargs="?",
required=True,
help="Certificate/key that will be registered",
)
register_parser.add_argument(
"-pi",
"--party-id",
metavar="PUBLIC_ID",
type=str,
nargs="?",
required=True,
help="ID of the party to which the certificate is to be registered (component ID).",
)
register_parser.add_argument(
"--upsert",
action="store_true",
help="Updates if certificate of given party id is already existing.",
)
generate.add_argument(
"--path",
type=str,
nargs="?",
required=False,
help="The path to the RESEARCHER|NODE component, in which certificate will be saved."
" By default it will overwrite existing certificate.",
)
initialize_magic_dev_environment_parsers
initialize_magic_dev_environment_parsers()
Initializes argument parser for the option to create development environment.
Source code in fedbiomed/common/cli.py
def initialize_magic_dev_environment_parsers(self) -> None:
"""Initializes argument parser for the option to create development environment."""
magic = self._subparsers.add_parser(
"certificate-dev-setup",
description="Prepares development environment by registering certificates "
"of each component created in a single clone of Fed-BioMed. Parses "
"configuration files ends with '.ini' that are created in 'etc' "
"directory. This setup requires to have one 'researcher' and "
"at least 2 nodes.",
help="Prepares development environment by registering certificates of each "
"component created in a single clone of Fed-BioMed.",
)
magic.set_defaults(func=self._create_magic_dev_environment)
initialize_optional
initialize_optional()
Initializes optional subparser
Optional subparsers are not going to be visible for the CLI that are inherited from CommonCLI class as long as intialize_optional
method is not executed.
Source code in fedbiomed/common/cli.py
def initialize_optional(self):
"""Initializes optional subparser
Optional subparsers are not going to be visible for the CLI that are
inherited from CommonCLI class as long as `intialize_optional` method
is not executed.
"""
self.initialize_magic_dev_environment_parsers()
self.initialize_version()
initialize_version
initialize_version()
Initializes argument parser for common options.
Source code in fedbiomed/common/cli.py
def initialize_version(self):
"""Initializes argument parser for common options."""
self._parser.add_argument(
"--version",
"-v",
action='version',
version=str(__version__),
help="Print software version",
)
parse_args
parse_args(args_=None)
Parse arguments after adding the arguments
Attention
Please make sure this method is called after all necessary arguments are set
Source code in fedbiomed/common/cli.py
def parse_args(self, args_=None):
"""Parse arguments after adding the arguments
!!! warning "Attention"
Please make sure this method is called after all necessary arguments are set
"""
args, unknown_args = self._parser.parse_known_args(args_)
if hasattr(args, "func"):
specs = get_method_spec(args.func)
if specs:
# If default function has 2 arguments
if len(specs) > 1:
return args.func(args, unknown_args)
# Run parser_args to raise error for unrecognized arguments
if unknown_args:
args = self._parser.parse_args(args_)
args.func(args)
else:
# Raise for unrecognized arguments
if unknown_args:
self._parser.parse_args(args_)
args.func()
else:
self._parser.print_help()
success staticmethod
success(message)
Prints given message with success tag
Parameters:
Name | Type | Description | Default |
---|---|---|---|
message | str | Message to print as successful operation | required |
Source code in fedbiomed/common/cli.py
@staticmethod
def success(message: str) -> None:
"""Prints given message with success tag
Args:
message: Message to print as successful operation
"""
print(f"{GRN}Operation successful! {NC}")
print(f"{BOLD}{message}{NC}")
ComponentDirectoryAction
ComponentDirectoryAction(*args, **kwargs)
Action for the argument config
This action class gets the config file name and set config object before executing any command.
Source code in fedbiomed/common/cli.py
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Sets config by default if option string for config is not present.
# The default is defined by the argument parser.
if (
not set(self.option_strings).intersection(set(sys.argv)) and
not set(["--help", "-h"]).intersection(set(sys.argv)) and
len(sys.argv) > 2
):
self._create_config(self.default)
super().__init__(*args, **kwargs)
Functions
set_component abstractmethod
set_component(component_dir)
Implements configuration import
Parameters:
Name | Type | Description | Default |
---|---|---|---|
component_dir | str | Name of the config file for the component | required |
Source code in fedbiomed/common/cli.py
@abstractmethod
def set_component(self, component_dir: str) -> None:
"""Implements configuration import
Args:
component_dir: Name of the config file for the component
"""