andy88836's picture
Deploy MOFScreen-Agent FastAPI backend
4d0da28 verified
Raw
History Blame Contribute Delete
3.93 kB
import abc
import argparse
import inspect
from argparse import ArgumentParser
from pricePrediction import config
class ArgParseable(abc.ABC):
@property
@abc.abstractmethod
def DESIRED_PARAMS_TO_ASK(self): #TOOD: Properties always apply to instances, not classes. to be modified
raise NotImplementedError()
@classmethod
def fromTypeStrToType(cls, strType: str):
if strType == "str":
return str
elif strType == "float":
return float
elif strType == "int":
return int
elif strType == "bool":
return bool
else:
raise ValueError("Parser not recognized type: "+str(strType))
@classmethod
def fromDefaultStrToValue(cls, argname:str, typeFun:type, defaultStr: str): #Currently not used
'''
TO BE USED if defaults in the docstring E.g. :param int batch_size: Batch size. defaults to %(config.BATCH_SIZE)s
:param argname:
:param typeFun:
:param defaultStr:
:return:
'''
if defaultStr is None or defaultStr == "None":
return None
return typeFun(defaultStr)
@classmethod
def getArgsForParser(cls):
from docstring_parser import parse
docstring = cls.__init__.__doc__
config_vars = vars(config)
config_vars = { "config."+key: val for key,val in config_vars.items() }
docstring = docstring%config_vars
docstring = parse(docstring)
signature = inspect.signature(cls.__init__)
name_to_default = {
k: v.default
for k, v in signature.parameters.items()
if v.default is not inspect.Parameter.empty
}
params = []
for elem in docstring.params:
if elem.arg_name in cls.DESIRED_PARAMS_TO_ASK:
typeFun = cls.fromTypeStrToType(elem.type_name)
# print(elem.default, elem.description)
### default = cls.fromDefaultStrToValue(elem.arg_name, typeFun, elem.default)
default = name_to_default[elem.arg_name]
params.append((elem.arg_name, typeFun, default, elem.description))
return params
# @classmethod
# def _addParamToArgParse(cls, parser:ArgumentParser, paramTuple):
# name, typeFun, default, help= paramTuple
# if typeFun == bool:
# if default is True:
# name = "no_"+name
# help = "Deactivate "+help
# parser.add_argument("--" + name, help=help+" Default=%(default)s", action="store_true")
# else:
# parser.add_argument("--"+name, type=typeFun, help=help+" Default=%(default)s", default=default)
# return parser
@classmethod
def addParamsToArgParse(cls, parser: ArgumentParser):
'''
:param parser: Argparser to which methods will be added
:return: the input parser but with added arguments
'''
for paramTuple in cls.getArgsForParser():
name, typeFun, default, help= paramTuple
if typeFun == bool:
if default is True:
action="store_false"
else:
action="store_true"
help += " Action: "+action
parser.add_argument("--" + name, help=help, action=action)
else:
parser.add_argument("--"+name, type=typeFun, help=help+" Default=%(default)s", default=default)
return parser
class MyArgParser(argparse.ArgumentParser):
def parse_args(self, args=None, namespace=None):
args = super().parse_args(args=args, namespace=namespace)
arg_groups = {}
for group in self._action_groups:
group_dict = {a.dest: getattr(args, a.dest, None) for a in group._group_actions}
arg_groups[group.title] = group_dict
return arg_groups