Created
December 1, 2014 20:34
-
-
Save darKoram/a71648a8e90c09bf38c0 to your computer and use it in GitHub Desktop.
pass json dict-as-string commandline args to functions or methods in a files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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