0

I have a Python utility script that accepts arguments in the commandline and executes tasks against an open source search tool called Elasticsearch.

But simply put, here is how it's currently being used:

Myscript.py create indexname http://localhost:9260
Myscript.py create indexname http://localhost:9260 IndexMap.json

I would like to make it so that the user of the script doesn't have to remember the order of the arguments to the script. How can I enable this in my script? I was thinking along the lines of a Unix-like argument passing. For example:

import os
import sys
import glob
import subprocess 

# collect command line arguments
commandline_args = sys.argv

# How to use this simple API:
#   create indexname http://localhost:9260 IndexMap.json

command_type = commandline_args[1]
index_name = commandline_args[2]
base_elasticsearch_url = commandline_args[3]
file_to_index = sys.argv[4] if len(sys.argv) > 4 else None


def run_curl(command, url):
    cmd = ['curl', command]
    url = url.split(' ')
    print 'sending command: '
    print cmd+url    
    return subprocess.check_output(cmd+url)

if (command_type == 'delete'):
    print 'About to run '+ command_type + ' on Index: ' + index_name
    command = '-XDELETE'
    composed_url = base_elasticsearch_url + '/' + index_name + '/'
    output = run_curl(command, composed_url)
    print 'output:'
    print output

# create Index # works!
# curl -XPOST 'localhost:9260/icrd_client_1 -d @clientmappings.json
if (command_type == 'create'):
    print 'About to run '+command_type+' for Index: '+index_name+' from filename: '+file_to_index
    command = '-XPOST'
    composed_url = base_elasticsearch_url + '/' + index_name +' -d ' + '@'+file_to_index
    output = run_curl(command, composed_url)
    print 'output:'
    print output
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Horse Voice
  • 8,138
  • 15
  • 69
  • 120

3 Answers3

1

If you're using Python 2.7 or newer, try argparse. For older versions, try optparse

ely
  • 74,674
  • 34
  • 147
  • 228
  • I have python: 2.7.5. The argparse looks like a very clunky mammoth. would you provide an example for how i can use it in my code? Do I need the sys.argv anymore? – Horse Voice Oct 29 '13 at 14:10
  • I don't understand the comment "The argparse looks like a very clunky mammoth." Can you be more specific? – ely Oct 29 '13 at 14:14
  • Well my real question is if there is a better tutorial I can use for argparse.. The one on the python site is a reference and I'm no expert at python. Any quick simple tutorials on this subject? – Horse Voice Oct 29 '13 at 14:17
  • Is [this tutorial](http://docs.python.org/2/howto/argparse.html) more helpful? – ely Oct 29 '13 at 14:21
  • `args = parser.parse_args()` << what does this do exactly? In my example, I can access the commandline entries like this: `command_type = commandline_args[1]`.. I don't understand the deal with parser.parse_args().. – Horse Voice Oct 29 '13 at 14:23
  • Open a Python interpreter and try it. It's not difficult to figure out. Make a simple program like the one from the tutorial, and then just start passing command line args and printing stuff. – ely Oct 29 '13 at 14:24
  • I don't understand how this will allow order independence? – Horse Voice Oct 29 '13 at 16:10
1

I'll suggest a simple elegant solution using python Dictionary, you can use the dictionary key instead using if statement, it's not the best option i'm sure it's just a bit more elegant.

import sys

def func1():
    print "I'm func1"

def func2():
    print "I'm func2"

def func3():
    print "I'm func3"

def func4():
    print "I'm default!"

def main():

    myCommandDict = {"arg1": func1(), "arg2": func2(), "arg3": func3(), "default": func4()}

    commandline_args = sys.argv

    for argument in commandline_args[1]:
        if argument in myCommandDict:
            myCommandDict[argument]
        else:
            myCommandDict["default"]

if __name__ == "__main__":
    main()

Edit main can be replaced with this option:

myCommandDict = {"arg1": func1, "arg2": func2, "arg3": func3, "default": func4}

commandline_args = sys.argv[1:]

for argument in commandline_args:
    if argument in myCommandDict:
        myCommandDict[argument]()
    else:
        myCommandDict["default"]()
Kobi K
  • 7,743
  • 6
  • 42
  • 86
  • This doesn't make sense to me. You have function calls as the values in the dictionary, so what you have is `{"arg1": None, "arg2": None, "arg3": None, "default": None}`. I think you want `"arg1: func1` and `myCommandDict[argument]()` instead. Also, you could replace the `"default"` key by using `myCommandDict.get(argument, func4)()` instead of the `if` `else` statements. – rlms Oct 29 '13 at 14:52
  • @sweeneyrod It can work both ways (tested), but i made an edit for the other option as you suggested with i have to say is a better approach. – Kobi K Oct 29 '13 at 15:00
0

You can also use Getopt(it works in a similar way to GNU Getopt)

Bezzi
  • 260
  • 3
  • 15