Skip to main content

builder

Handles the building/saving of the configurations from the Spock config classes

ConfigArgBuilder Objects#

class ConfigArgBuilder()

Automatically generates dataclass instances from config file(s)

This class builds out necessary arguments from *args classes, reads the arguments from specified config file(s), and subsequently (via chained call to generate) generates each class instance based on the necessary field values for each backend class instance

Attributes:

  • _args - all command line args
  • _arg_namespace - generated argument namespace
  • _builder_obj - instance of a BaseBuilder class
  • _dict_args - dictionary args from the command line
  • _payload_obj - instance of a BasePayload class
  • _saver_obj - instance of a BaseSaver class
  • _tune_payload_obj - payload for tuner related objects -- instance of TunerPayload class
  • _tune_obj - instance of TunerBuilder class
  • _tuner_interface - interface that handles the underlying library for sampling -- instance of TunerInterface
  • _tuner_state - current state of the hyper-parameter sampler
  • _tune_namespace - namespace that hold the generated tuner related parameters
  • _sample_count - current call to the sample function
  • _fixed_uuid - fixed uuid to write the best file to the same path _configs = configs if configs is None else [Path(c) for c in configs]
  • _lazy - flag to lazily find @spock decorated classes registered within sys.modules["spock"].backend.config thus alleviating the need to pass all @spock decorated classes to *args
  • _no_cmd_line - turn off cmd line args
  • _desc - description for help
  • _salt - salt use for crypto purposes
  • _key - key used for crypto purposes

__init__#

def __init__(*args, *, configs: Optional[List] = None, desc: str = "", lazy: bool = False, no_cmd_line: bool = False, s3_config: Optional[_T] = None, key: Optional[Union[str, ByteString]] = None, salt: Optional[str] = None, **kwargs, ,)

Init call for ConfigArgBuilder

Arguments:

  • *args - tuple of spock decorated classes to process
  • configs - list of config paths
  • desc - description for help
  • lazy - attempts to lazily find @spock decorated classes registered within sys.modules["spock"].backend.config as well as the parents of any lazily inherited @spock class thus alleviating the need to pass all @spock decorated classes to *args
  • no_cmd_line - turn off cmd line args
  • s3_config - s3Config object for S3 support
  • salt - either a path to a prior spock saved salt.yaml file or a string of the salt (can be an env reference)
  • key - either a path to a prior spock saved key.yaml file, a ByteString of the key, or a str of the key (can be an env reference)
  • **kwargs - keyword args

__call__#

def __call__(*args, **kwargs) -> _T

Call to self to allow chaining

Arguments:

  • *args - non-keyword args
  • **kwargs - keyword args

Returns:

  • ConfigArgBuilder - self instance

generate#

def generate() -> Spockspace

Generate method that returns the actual argument namespace

Returns:

argument namespace consisting of all config classes

tuner_status#

@propertydef tuner_status() -> Dict

Returns a dictionary of all the necessary underlying tuner internals to report the result

best#

@propertydef best() -> Spockspace

Returns a Spockspace of the best hyper-parameter config and the associated metric value

salt#

@propertydef salt()

Returns the salt for crypto

key#

@propertydef key()

Returns the key for crypto

sample#

def sample() -> Spockspace

Sample method that constructs a namespace from the fixed parameters and samples from the tuner space to generate a Spockspace derived from both

Returns:

argument namespace(s) -- fixed + drawn sample from tuner backend

tuner#

def tuner(tuner_config: _T) -> _T

Chained call that builds the tuner interface for either optuna or ax depending upon the type of the tuner_obj

Arguments:

  • tuner_config - a class of type optuna.study.Study or AX****

Returns:

self so that functions can be chained

_print_usage_and_exit#

def _print_usage_and_exit(msg: Optional[str] = None, sys_exit: bool = True, exit_code: int = 1) -> None

Prints the help message and exits

Arguments:

  • msg - message to print pre exit

Returns:

None

_handle_tuner_objects#

def _handle_tuner_objects(tune_args: List, s3_config: Optional[_T], kwargs: Dict) -> Tuple

Handles creating the tuner builder object if @spockTuner classes were passed in

Arguments:

  • tune_args - list of tuner classes
  • s3_config - s3Config object for S3 support
  • kwargs - optional keyword args

Returns:

tuner builder object or None

_verify_attr#

@staticmethoddef _verify_attr(args: Tuple) -> None

Verifies that all the input classes are attr based

Arguments:

  • args - tuple of classes passed to the builder

Returns:

None

_strip_tune_parameters#

@staticmethoddef _strip_tune_parameters(args: Tuple) -> Tuple[List, List]

Separates the fixed arguments from any hyper-parameter arguments

Arguments:

  • args - tuple of classes passed to the builder

Returns:

  • fixed_args - list of fixed args
  • tune_args - list of args destined for a tuner backend

_handle_cmd_line#

def _handle_cmd_line() -> argparse.Namespace

Handle all cmd line related tasks

Config paths can enter from either the command line or be added in the class init call as a kwarg (configs=[]) -- also trigger the building of the cmd line overrides for each fixed and tunable objects

Returns:

  • args - namespace of args

_build_override_parsers#

def _build_override_parsers(desc: str) -> argparse.Namespace

Creates parsers for command-line overrides

Builds the basic command line parser for configs and help then iterates through each attr instance to make namespace specific cmd line override parsers -- handles calling both the fixed and tunable objects

Arguments:

  • desc - argparser description

Returns:

  • args - argument namespace

_get_from_kwargs#

@staticmethoddef _get_from_kwargs(args: argparse.Namespace, configs: List)

Get configs from the configs kwarg

Arguments:

  • args - argument namespace
  • configs - config kwarg

Returns:

  • args - arg namespace

_get_payload#

def _get_payload(payload_obj: Type[AttrPayload], input_classes: Tuple, ignore_args: List) -> Dict

Get the parameter payload from the config file(s)

Calls the various ways to get configs and then parses to retrieve the parameter payload - make sure to call deep update so as to not lose some parameters when only partially updating the payload

Arguments:

  • payload_obj - current payload object to call
  • input_classes - classes to use to get payload
  • ignore_args - args that were decorated for hyper-parameter tuning

Returns:

  • payload - dictionary of parameter values

_save#

def _save(payload: Spockspace, file_name: str = None, user_specified_path: Path = None, create_save_path: bool = True, extra_info: bool = True, file_extension: str = ".yaml", tuner_payload: Optional[Spockspace] = None, fixed_uuid: str = None) -> _T

Private interface -- saves the current config setup to file with a UUID

Arguments:

  • payload - Spockspace to save
  • file_name - name of file (will be appended with .spock.cfg.file_extension) -- falls back to just uuid if None
  • user_specified_path - if user provides a path it will be used as the path to write
  • create_save_path - bool to create the path to save if called
  • extra_info - additional info to write to saved config (run date and git info)
  • file_extension - file type to write (default: yaml)
  • tuner_payload - tuner level payload (unsampled)
  • fixed_uuid - fixed uuid to allow for file overwrite

Returns:

self so that functions can be chained

save#

def save(file_name: str = None, user_specified_path: Union[Path, str] = None, create_save_path: bool = True, extra_info: bool = True, file_extension: str = ".yaml", add_tuner_sample: bool = False) -> _T

Saves the current config setup to file with a UUID

Arguments:

  • file_name - name of file (will be appended with .spock.cfg.file_extension) -- falls back to just uuid if None
  • user_specified_path - if user provides a path it will be used as the path to write
  • create_save_path - bool to create the path to save if called
  • extra_info - additional info to write to saved config (run date and git info)
  • file_extension - file type to write (default: yaml)
  • add_tuner_sample - save the current tuner sample to the payload

Returns:

self so that functions can be chained

save_best#

def save_best(file_name: str = None, user_specified_path: Path = None, create_save_path: bool = True, extra_info: bool = True, file_extension: str = ".yaml") -> _T

Saves the current best config setup to file

Arguments:

  • file_name - name of file (will be appended with .spock.cfg.file_extension) -- falls back to just uuid if None
  • user_specified_path - if user provides a path it will be used as the path to write
  • create_save_path - bool to create the path to save if called
  • extra_info - additional info to write to saved config (run date and git info)
  • file_extension - file type to write (default: yaml)

Returns:

self so that functions can be chained

config_2_dict#

@propertydef config_2_dict() -> Dict

Dictionary representation of the arg payload

spockspace_2_dict#

def spockspace_2_dict(payload: Spockspace) -> Dict

Converts an input SpockSpace into a dictionary

Arguments:

  • payload - SpockSpace generated by the ConfigArgBuilder

Returns:

dictionary representation of the SpockSpace

obj_2_dict#

def obj_2_dict(obj: Union[_C, List[_C], Tuple[_C, ...]]) -> Dict[str, Dict]

Converts spock classes from a Spockspace into their dictionary representations

Arguments:

  • obj - single spock class or an iterable of spock classes

Returns:

dictionary where the class names are keys and the values are the dictionary representations

evolve#

def evolve(*args: _C) -> Spockspace

Function that allows a user to evolve the underlying spock classes with instantiated spock objects

This will map the differences between the passed in instantiated objects and the underlying class definitions to the underlying namespace -- this essentially allows you to 'evolve' the Spockspace similar to how attrs allows for class evolution -- returns a new Spockspace object

Arguments:

  • *args - variable number of instantiated @spock decorated classes to evolve parameters with

Returns:

  • new_arg_namespace - Spockspace evolved with *arg @spock decorated classes

Raises:

  • _SpockEvolveError - if multiple of the same instance are passed as input or if the one or more of the inputs are not within the set of original input classes

_recurse_upwards#

def _recurse_upwards(new_arg_namespace: Spockspace, current_cls: str, all_cls: Dict) -> Tuple[Spockspace, Dict]

Using the underlying graph work recurse upwards through the parents and swap in the correct values

Arguments:

  • new_arg_namespace - new Spockspace object
  • current_cls - current name of the cls
  • all_cls - dict of the variable number of @spock decorated classes to evolve parameters with

Returns:

modified new_arg_namespace and the updated evolve class dict

_set_matching_attrs_by_name_args#

@staticmethoddef _set_matching_attrs_by_name_args(current_cls_name: str, parent_cls_name: str, all_cls: Dict) -> Dict

Sets the value of an attribute by matching it to a spock class name

Arguments:

  • current_cls_name - current name of the changed class
  • parent_cls_name - name of the parent class that contains a reference to the current class
  • all_cls - dict of the variable number of @spock decorated classes to evolve parameters with

Returns:

modified all_cls dictionary

_set_matching_attrs_by_name#

@staticmethoddef _set_matching_attrs_by_name(new_arg_namespace: Spockspace, current_cls_name: str, parent_cls_name: str) -> Spockspace

Sets the value of an attribute by matching it to a spock class name

Arguments:

  • new_arg_namespace - new Spockspace object
  • current_cls_name - current name of the changed class
  • parent_cls_name - name of the parent class that contains a reference to the current class

Returns:

modified new_arg_namespace

_maybe_crypto#

def _maybe_crypto(key: Optional[Union[str, ByteString]], salt: Optional[str], s3_config: Optional[_T] = None, salt_len: int = 16) -> Tuple[str, ByteString]

Handles setting up the underlying cryptography needs

Arguments:

  • salt - either a path to a prior spock saved salt.yaml file or a string of the salt (can be an env reference)
  • key - either a path to a prior spock saved key.yaml file, a ByteString of the key, or a str of the key (can be an env reference)
  • s3_config - s3Config object for S3 support
  • salt_len - length of the salt to create

Returns:

tuple containing a salt and a key that spock can use to hide parameters

_get_salt#

def _get_salt(salt: Optional[str], env_resolver: EnvResolver, salt_len: int, s3_config: Optional[_T] = None) -> str

Arguments:

  • salt - either a path to a prior spock saved salt.yaml file or a string of the salt (can be an env reference)
  • env_resolver - EnvResolver class to handle env variable resolution if needed
  • salt_len - length of the salt to create
  • s3_config - s3Config object for S3 support

Returns:

salt as a string

_get_key#

def _get_key(key: Optional[Union[str, ByteString]], env_resolver: EnvResolver, s3_config: Optional[_T] = None) -> ByteString

Arguments:

  • key - either a path to a prior spock saved key.yaml file, a ByteString of the key, or a str of the key (can be an env reference)
  • env_resolver - EnvResolver class to handle env variable resolution if needed
  • s3_config - s3Config object for S3 support

Returns:

key as ByteString

_handle_yaml_read#

@staticmethoddef _handle_yaml_read(value: str, access: str, s3_config: Optional[_T] = None, encode: bool = False) -> Union[str, ByteString]

Reads in a salt/key yaml

Arguments:

  • value - path to the key/salt yaml
  • access - which variable name to use from the yaml
  • s3_config - s3Config object for S3 support