Skip to content

Instantly share code, notes, and snippets.

@zlinuxboy
Forked from darKoram/cli.py
Created October 28, 2021 00:50
Show Gist options
  • Save zlinuxboy/124c79578da043ee7aae9b8d52160cd4 to your computer and use it in GitHub Desktop.
Save zlinuxboy/124c79578da043ee7aae9b8d52160cd4 to your computer and use it in GitHub Desktop.
pass json dict-as-string commandline args to functions or methods in a files
import os
# based on
# http://code.activestate.com/recipes/577122-transform-command-line-arguments-to-args-and-kwarg/
def _method_info_from_argv(argv=None):
"""Command-line -> method call arg processing.
- positional args:
a b -> method('a', 'b')
- intifying args:
a 123 -> method('a', 123)
- json loading args:
a '["pi", 3.14, null]' -> method('a', ['pi', 3.14, None])
- keyword args:
a foo=bar -> method('a', foo='bar')
- using more of the above
1234 'extras=["r2"]' -> method(1234, extras=["r2"])
@param argv {list} Command line arg list. Defaults to `sys.argv`.
@returns (<method-name>, <args>, <kwargs>)
"""
import json
import sys
if argv is None:
argv = sys.argv
file_name, method_name, arg_strs = argv[1], argv[2], argv[3:]
args = []
kwargs = {}
for s in arg_strs:
if s.count('=') == 1:
key, value = s.split('=', 1)
else:
key, value = None, s
try:
value = json.loads(value)
except ValueError:
pass
if key:
kwargs[key] = value
else:
args.append(value)
return file_name, method_name, args, kwargs
if __name__ == "__main__":
import sys
print sys.argv
file_name, method_name, args, kwargs = _method_info_from_argv(sys.argv)
if file_name.startswith('/'):
abs_path = file_name
else:
abs_path = os.path.join(os.getcwd(),file_name)
if not os.path.exists(abs_path):
print "Error: {} does not exist".format(abs_path)
dirname,file_name = os.path.dirname(abs_path),os.path.basename(abs_path)
sys.path.append(dirname)
module_name = file_name.rstrip(".py")
import importlib
module = importlib.import_module(module_name, package=None)
print "dir(module)",dir(module)
print "module ", module
print "globals ", globals()
print "getattr(module_name, method_name) ", getattr(module,method_name)
if method_name == "main":
sys.argv = sys.argv[1:]
sys.argv.remove("main")
sys.exit(execfile(abs_path))
else:
#rv = globals()['module'](method_name)(*args, **kwargs)
rv = getattr(module,method_name)(*args,**kwargs)
sys.exit(rv)
# based on
# http://code.activestate.com/recipes/577122-transform-command-line-arguments-to-args-and-kwarg/
I had a further use case of needing to execute a file or command within a file remotely by passing a stringified json dictionary. It might be nicer to create a module that can be imported since i will probably be controlling all the python files, but in case I don't, I've written it as a file "cli.py" that can be copied along with the file to be executed.
Called like this
python cli.py my_actual_file.py method_name --arg1 <arg1> --arg2 <arg2> ...
if method_name == "main" then call execfile passing in the appropriate sys.argv
my_actual_file.py must accept the args either using argparse.parser.pare_args() in a main() function or
as args to the "metnod_name"
With this, I can do things like
python cli.py copy_db_schema.py main --source_db "{'host': 'server1', 'port': 5432, 'user': 'me', 'pwd': '***'}" --dest_db ...similar...
or
python cli.py copy_db_schema.py list_tables --source_db "{'host': 'server1', 'port': 5432, 'user': 'me', 'pwd': '***'}"
where list_tables is a method accepting source_db dict params
Essentially, i'm wrapperizing your _method_info_from_argv
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment