Get input from user at command line and use that input to feed variables into Python script
<p>I have a script named <code>GetStats.py</code>.  </p>

<p>At a high level, the <code>GetStats.py</code> script does the following:</p>

<p>1) makes a connection to an external database
2) retrieves some data from this database
3) writes the data retrieved in step 2 to a csv file</p>

<p>Importantly, the <code>GetStats.py</code> script references a configuration (.cfg) file, which includes (among many other details), the IP address and server details of the specific database to which to connect.</p>

<p>The <code>GetStats.py</code> script requires that the user pass the following parameters on the command line:</p>

<p>a) the number of days of data to retrieve (i.e. the look back period)
b) the granularity of the data (which is either hourly or daily)
c) whether to include a limited set of data (which takes about 30 minutes to run) or the full set of data (which takes about 1 hour and 15 minutes to run)</p>

<p>I also have a batch file that I use to run everything.  The batch file looks as follows:</p>

<pre><code>GetStats.py Client_A.cfg 30 -d -full
GetStats.py Client_B.cfg 30 -d -full
GetStats.py Client_C.cfg 30 -d -full
GetStats.py Client_D.cfg 30 -d -full
GetStats.py Client_E.cfg 30 -d -full
... and so on up to Client_M
</code></pre>

<p>As we can see from the batch file above, the GetStats.py script is called and it runs against Client_A through Client_E for a period of 30 days, with daily granularity and returns the full set of data.</p>

<p>The problem is that if I want to change any of these parameters (e.g. change the number of days in the look back period, the data granularity and/or the set of data to return), I need to edit the batch file directly, and that process can take several minutes.  </p>

<p>I'd like to streamline the process such that the user is prompted for the following <strong>only once</strong> at the command line once the batch file is run:</p>

<p>"Please enter the number of days to look back: "</p>

<p>"Please enter the granularity of the data: "</p>

<p>"Please enter the data set to return: "</p>

<p>I've given some thought as to how to incorporate these three parameters <strong>directly</strong> into the GetStats.py script.  </p>

<p>But, I think I will run into a problem because the batch file will run the GetStats.py script and then prompt the user for the 3 parameters above <strong>each time</strong> the GetStats.py script is called (which is currently 13 times).  </p>

<p>I don't want the user to have to enter "30", "-d" and "-full" a total of 13 times.  I'd like the user to enter "30", "-d" and "-full" <strong>only once</strong>.</p>

<p>Does anyone have any ideas how I can prompt the user for the above-mentioned 3 parameters <strong>only once</strong> after the batch file is run?</p>

<p>Thanks!</p>

<p>Consider sourcing your <em>GetStats.py</em> as a module in a different .py script that receives user input via <code>input()</code> (or <code>raw_input()</code> in Python 2). In this way, you do no need a batch file or entering parameters via command line which is not a user-friendly interface. Plus, you can loop through all client types for a DRY-er approach using <code>string.ascii_uppercase</code>. Below is setup:</p>

<p><strong>GetStats.py</strong> </p>

<p><em>(wrap entire script in a defined module receiving the params previously sent via command line, no longer the <code>sys.argv[]</code> collection)</em></p>

<pre><code>def processData(clienttype, lookbackdaysparam, granularityparam, datasettypeparam):
   #...script...
</code></pre>

<p><strong>UserInput.py</strong> </p>

<p><em>(place in same directory as GetStats.py; consider controlling for numeric/string values)</em></p>

<pre><code>import GetStats
from string import ascii_uppercase

lookbackdays = ''; granularity = ''; datasettype = ''

# LOOP RUNS INFINITELY PROMPTING INPUT UNTIL USER FILLS OUT EACH ONE:
while True:    
    if lookbackdays == '':
        lookbackdays = input("Please enter the number of days to look back: ")

    elif granularity == '':
        granularity = input("Please enter the granularity of the data: ")

    elif datasettype == '':
        datasettype = input("Please enter the data set to return: ")

    else:
        break

# LOOPS THROUGH LETTERS A-M
for c in ascii_uppercase[0:13]:
    GetStats.processData('Client_'+c+'.cfg', lookbackdays, granularity, datasettype)

print("Successfully processed data!")
</code></pre>

<hr>

<p><strong>Tkinter</strong> GUI</p>

<p>Even better, consider an actual GUI interface using the <a href="https://docs.python.org/2/library/tkinter.html" rel="nofollow">tkinter</a> module (pre-installed in Python 3):</p>

<pre><code>import GetStats
from tkinter import *
from tkinter import ttk 
from string import ascii_uppercase

class GUIapp():

    def __init__(self):
        self.root = Tk()
        self.buildControls()
        self.root.mainloop()

    def buildControls(self):        
        self.root.wm_title("Get Stats Menu")
        self.guiframe = Frame(self.root, width=2500, height=500, bd=1, relief=FLAT)
        self.guiframe.pack(padx=5, pady=5)

        # IMAGE
        self.photo = PhotoImage(file="Stats.png")
        self.imglbl = Label(self.guiframe, image=self.photo)
        self.imglbl.photo = self.photo
        self.imglbl.grid(row=0, sticky=W, padx=5, pady=5)
        self.imglbl = Label(self.guiframe, text="Enter parameters for data request",
                            font=("Arial", 12)).\
                            grid(row=0, column=1, sticky=W, padx=5, pady=5)

        # PERIOD DAYS 
        self.periodDayslbl = Label(self.guiframe, text="Please enter the number of days to look back: ",
                                  font=("Arial", 10)).grid(row=1, sticky=W, padx=5, pady=5)
        self.periodDaysvar = StringVar()
        self.periodDaystxt = Entry(self.guiframe, textvariable=self.periodDaysvar,
                                  relief=SOLID, font=("Arial", 10), width=34).\
                                  grid(row=1, column=1, sticky=W, padx=5, pady=5)

        # DATA GRANULARITY
        self.granularitylbl = Label(self.guiframe, text="Please enter the granularity of the data: ",
                                font=("Arial", 10)).grid(row=2, sticky=W, padx=5, pady=5)
        self.granularityvar = StringVar()
        self.granularitytxt = Entry(self.guiframe, textvariable=self.granularityvar,
                                relief=SOLID, font=("Arial", 10), width=34).\
                                grid(row=2, column=1, sticky=W, padx=5, pady=5)

        # DATASET TO RETURN
        self.datasetTypelbl = Label(self.guiframe, text="Please enter the data set to return: ",
                                font=("Arial", 10)).grid(row=3, sticky=W, padx=5, pady=5)
        self.datasetTypevar = StringVar()
        self.datasetTypetxt = Entry(self.guiframe, textvariable=self.datasetTypevar, relief=SOLID,
                                font=("Arial", 10), width=34).\
                                grid(row=3, column=1, sticky=W, padx=5, pady=5)

        # PROCESS BUTTON 
        self.btnoutput = Button(self.guiframe, text="PROCESS",
                                font=("Arial", 10), width=25, command=self.processData).\
                                grid(row=4, column=1, sticky=W, padx=10, pady=5)

    def processData(self):
        if self.periodDaysvar.get() != '' and self.granularityvar.get() != '' and self.datasetTypevar.get() != '':    
            for c in ascii_uppercase[0:13]:
                GetStats.processData('Client_'+c+'cfg', self.periodDaysvar.get(), 
                                     self.granularityvar.get(), self.datasetTypevar.get())                   
                messagebox.showinfo("SUCCESFUL OUTPUT", "Successfully processed data!")
        else:
            messagebox.showerror("MISSING FIELD", "Please enter all fields to process request.")

if __name__ == "__main__":
    GUIapp()
</code></pre>

<p><strong>GUI</strong> Menu <em>(image is a small pic named Stats.png in same directory as script)</em></p>

<p><a href="https://i.stack.imgur.com/g8PSL.png" rel="nofollow"><img src="https://i.stack.imgur.com/g8PSL.png" alt="GUI Menu"></a></p>

<p>Message Boxes <em>(called on Process button click)</em></p>

<p><a href="https://i.stack.imgur.com/qnoxe.png" rel="nofollow"><img src="https://i.stack.imgur.com/qnoxe.png" alt="GUI Success Message"></a>
<a href="https://i.stack.imgur.com/vFUc3.png" rel="nofollow"><img src="https://i.stack.imgur.com/vFUc3.png" alt="GUI Error Message"></a></p>

python batch-file