77from sahi .scripts .coco_error_analysis import analyse
88from sahi .scripts .coco_evaluation import evaluate
99from sahi .scripts .slice_coco import slicer
10- from sahi .utils .import_utils import print_environment_info
10+ from sahi .utils .package_utils import print_environment_info
11+ from sahi .utils .cli_helper import make_click_command
1112
1213
13- @click .group ()
14+ @click .group (help = "SAHI command-line utilities: slicing-aided high-resolution inference and COCO tools" )
1415def cli ():
16+ """Top-level click group for SAHI CLI."""
1517 pass
1618
1719coco_app = {
@@ -31,90 +33,23 @@ def cli():
3133 "env" : print_environment_info ,
3234}
3335
34- def _make_callback (obj ):
35- """Return a callable suitable for click.Command:
36- - if obj is callable, call it with whatever click passes;
37- - otherwise print the object (e.g. version string).
38- """
39- if callable (obj ):
40- def _cb (* args , ** kwargs ):
41- return obj (* args , ** kwargs )
42- else :
43- def _cb (* args , ** kwargs ):
44- click .echo (str (obj ))
45- return _cb
46-
47- import inspect
48-
49-
50- def _click_params_from_signature (func ):
51- """Create a list of click.Parameter (Argument/Option) objects from a Python
52- callable's signature. This provides a lightweight automatic mapping so
53- CLI options are available without manually writing decorators.
54-
55- Rules (simple, pragmatic):
56- - positional parameters without default -> click.Argument (required)
57- - parameters with a default -> click.Option named --param-name
58- - bool defaults -> is_flag option
59- - list/tuple defaults -> multiple option
60- - skip *args/**kwargs and (self, cls)
61- - use annotation or default value to infer type when possible
62- """
63- params = []
64- sig = inspect .signature (func )
65- for name , p in sig .parameters .items ():
66- # skip common unrepresentable params
67- if name in ("self" , "cls" ):
68- continue
69- if p .kind in (inspect .Parameter .VAR_POSITIONAL , inspect .Parameter .VAR_KEYWORD ):
70- # skip *args/**kwargs
71- continue
72-
73- if p .default is inspect ._empty :
74- # required positional argument
75- params .append (click .Argument ([name ]))
76- else :
77- opt_name = f"--{ name } "
78- # boolean flags
79- if isinstance (p .default , bool ):
80- params .append (click .Option ([opt_name ], is_flag = True , default = p .default , help = f"(auto) default={ p .default } " ))
81- # lists/tuples -> multiple
82- elif isinstance (p .default , (list , tuple )):
83- params .append (click .Option ([opt_name ], multiple = True , default = tuple (p .default ), help = "(auto) multiple" ))
84- else :
85- # infer type from annotation or default value
86- param_type = None
87- if p .annotation is not inspect ._empty and p .annotation in (int , float , str , bool ):
88- param_type = p .annotation
89- elif p .default is not None :
90- param_type = type (p .default )
91- else :
92- param_type = str
93- params .append (click .Option ([opt_name ], default = p .default , type = param_type , help = f"(auto) default={ p .default } " ))
94- return params
95-
96-
97- def _make_click_command (name , func ):
98- """Build a click.Command for `func`, auto-generating params from signature if callable."""
99- params = _click_params_from_signature (func ) if callable (func ) else []
100- return click .Command (name , params = params , callback = _make_callback (func ))
101-
10236
10337def app () -> None :
10438 """Cli app."""
105- #fire.Fire(sahi_app)
106- # for loop to add commands to cli
39+
10740 for command_name , command_func in sahi_app .items ():
10841 if isinstance (command_func , dict ):
109- # add subcommands
110- sub_cli = click .Group (command_name )
42+ # add subcommands (create a named Group with help text)
43+ sub_cli = click .Group (command_name , help = f" { command_name } related commands" )
11144 for sub_command_name , sub_command_func in command_func .items ():
112- sub_cli .add_command (_make_click_command (sub_command_name , sub_command_func ))
45+ sub_cli .add_command (make_click_command (sub_command_name , sub_command_func ))
11346 cli .add_command (sub_cli )
11447 else :
115- cli .add_command (_make_click_command (command_name , command_func ))
48+ cli .add_command (make_click_command (command_name , command_func ))
11649
11750 cli ()
11851
52+
11953if __name__ == "__main__" :
120- cli ()
54+ # build the application (register commands) and run
55+ app ()
0 commit comments