Package: smart-arg
Smart Argument Suite (smart-arg)Smart Argument Suite (smart-arg) is a slim and handy Python library that helps one work safely and conveniently
with the arguments that are represented by an immutable argument container class' fields
(NamedTupleordataclassout-of-box),
and passed through command-line interfaces.smart-argpromotes arguments type-safety, enables IDEs' code autocompletion and type hints
functionalities, and helps one produce correct code.Quick startThesmart-argpackage is available throughpip.pip3installsmart-argUsers can bring or define, if not already, their argument container class -- aNamedTupleordataclass,
and then annotate it withsmart-argdecorator@arg_suitein their Python scripts.Now an argument container class instance, e.g.my_argofMyArgclass, once created, is ready to be serialized by thesmart-argAPI --my_arg.__to_argv__()to a sequence of strings, passed through the command-line interface
and then deserialized back to an instance again bymy_arg = MyArg.__from_argv__(sys.argv[1:]).importsysfromtypingimportNamedTuple,List,Tuple,Dict,Optionalfromsmart_argimportarg_suite# Define the argument container class@arg_suiteclassMyArg(NamedTuple):"""MyArg is smart! (docstring goes to description)"""nn:List[int]# Comments go to argparse helpa_tuple:Tuple[str,int]# a random tuple argumentencoder:str# Text encoder typeh_param:Dict[str,int]# Hyperparametersbatch_size:Optional[int]=Noneadp:bool=True# bool is a bit trickyembedding_dim:int=100# Size of embedding vectorlr:float=1e-3# Learning ratedefcli_interfaced_job_scheduler():"""This is to be called by the job scheduler to set up the job launching command,i.e., producer side of the Python job arguments"""# Create the argument container instancemy_arg=MyArg(nn=[3],a_tuple=("str",1),encoder='lstm',h_param={},adp=False)# The patched argument container class requires keyword arguments to instantiate the class# Serialize the argument to command-line representationargv=my_arg.__to_argv__()cli='my_job.py '+' '.join(argv)# Schedule the job with command line `cli`print(f"Executing job:\n{cli}")# Executing job:# my_job.py --nn 3 --a_tuple str 1 --encoder lstm --h_param --batch_size None --adp False --embedding_dim 100 --lr 0.001defmy_job(my_arg:MyArg):"""This is the actual job defined by the input argument my_arg,i.e., consumer side of the Python job arguments"""print(my_arg)# MyArg(nn=[3], a_tuple=('str', 1), encoder='lstm', h_param={}, batch_size=None, adp=False, embedding_dim=100, lr=0.001)# `my_arg` can be used in later script with a typed manner, which help of IDEs (type hints and auto completion)# ...print(f"My network has{len(my_arg.nn)}layers with sizes of{my_arg.nn}.")# My network has 1 layers with sizes of [3].# my_job.pyif__name__=='__main__':# Deserialize the command-line representation of the argument back to a container instancearg_deserialized:MyArg=MyArg.__from_argv__(sys.argv[1:])# Equivalent to `MyArg(None)`, one positional arg required to indicate the arg is a command-line representation.my_job(arg_deserialized)> python my_job.py -husage: my_job.py [-h] --nn [int [int ...]] --a_tuple str int --encoder str--h_param [str:int [str:int ...]] [--batch_size int][--adp {True,False}] [--embedding_dim int] [--lr float]MyArg is smart! (docstring goes to description)optional arguments:-h, --help            show this help message and exit--nn [int [int ...]]  (List[int], required) Comments go to argparse help--a_tuple str int     (Tuple[str, int], required) a random tuple argument--encoder str         (str, required) Text encoder type--h_param [str:int [str:int ...]](Dict[str, int], required) Hyperparameters--batch_size int      (Optional[int], default: None)--adp {True,False}    (bool, default: True) bool is a bit tricky--embedding_dim int   (int, default: 100) Size of embedding vector--lr float            (float, default: 0.001) Learning ratePromoted practicesFocus on defining the arguments diligently, and let thesmart-arg(backed byargparse.ArgumentParser)
work its magic around command-line interface.Always work directly with argument container class instances when possible, even if you only need to generate the command-line representation.Stick to the default behavior and the basic features, think twice before using any of theadvanced features.More detailFor more features and implementation detail, please refer to thedocumentation.ContributingPlease readCONTRIBUTING.mdfor details on our code of conduct, and the process for submitting pull requests to us.LicenseThis project is licensed under the BSD 2-CLAUSE LICENSE - see theLICENSE.mdfile for details