In my python script,i need to read the input ".csv files" from the Input directory(/home/ubuntu/pythontraining/InputCsv) and store the result in two separate output directories i.e,StudentDetails(/home/ubuntu/pythontraining/StudentDetails) and FacultyDetails(/home/ubuntu/pythontraining/FacultyDetails).I want to specify the directory path as a command line arguments using argparser.Can someone help me how to specify the directory path as a command line arguments using python's argparser?
import argparse
parser=argparse.ArgumentParser()
parser.add_argument("Input_directory")
parser.add_argument("Student_directory")
parser.add_argument("Faculty_directory")
You can try below example -
import argparse
def some_args():
parser = argparse.ArgumentParser(description='Some description')
parser.add_argument('--input-dir', help='Input directory')
parser.add_argument('--student-dir', help='Input Student directory')
parser.add_argument('--faculty-dir', help='Input Faculty directory')
return parser.parse_args()
def main():
args = some_args()
input_path = args.input_dir
student_path = args.student_dir
faculty_path = args.faculty_dir
print (input_path ) #prints your input_path which you passed
print (student_path ) #prints your student_path which you passed
print (faculty_path ) #prints your faculty_path which you passed
if __name__ == '__main__':
main()
Command line argument to be as -
python foo.py --input-dir <some_arg> --student-dir <some_arg> --faculty-dir <some_arg>
Reference
https://docs.python.org/3/howto/argparse.html
Related
This is my first post, so please excuse any missing info or stupid questions.So what I am trying to do is run a command line python script (I'm in a Windows machine), pass it 2 arguments, check if the arguments were passed, if not, display an error message specific to that argument. I am getting a missing argument error, but it isnt displaying the message I would like (defined in the function). I'm not sure if I didn't create the function properly, or if I am missing something. I also want to check if the arguments passed are correct strings, not int, but it seems that the arguments are defaulting to strings, so checking if they are int is not working either.
Can someone give me a hint or point me in the right direction? I've been searching online but havent found anything that has answered this question. I am brand new to python, so still learning how to read documentation properly (seems like there are too few examples for me to understand the docs). Here is the code I am using:
import argparse
#parser to create and grab args from CLI
parser = argparse.ArgumentParser()
parser.add_argument("-i", help="File path of original folder")
parser.add_argument("-o", help="File path of output folder")
args = parser.parse_args()
#check if args have been passed and display error if missing
def check_args(input_path,output_path):
if input_path == None:
print("Please input a valid folder path for original folder destination")
elif output_path == None:
print("Please input a valid folder path for output folder destination")
else:
return args
#grab first and sec argument
input_path = args.i
output_path = args.o
check_args(input_path, output_path)
Output:
Program>python JPGtoPNG_conv.py -i 3 -o
usage: JPGtoPNG_conv.py [-h] [-i I] [-o O]
JPGtoPNG_conv.py: error: argument -o: expected one argument
Thanks so much for any help!
The code below should do the job for you
import argparse
import sys
class MyParser(argparse.ArgumentParser):
def error(self, message):
sys.stderr.write('error: %s\n' % message)
self.print_help()
sys.exit(2)
parser = MyParser()
parser.add_argument("-i", help="File path of original folder", required=True)
parser.add_argument("-o", help="File path of output folder", required=True)
args = parser.parse_args()
# grab first and sec argument
input_path = args.i
output_path = args.o
I am passing a single, positional argument string called FILE, but when no arguments are passed, I want it to print a usage statement.
Every time I write './files.py' in my command-line with no arguments after it, my code does nothing. What am I doing wrong?
import argparse
import re
#--------------------------------------------------
def get_args():
"""get arguments"""
parser = argparse.ArgumentParser(
description='Create Python script',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('FILE', help='Pass a file', type=str)
return parser.parse_args()
#--------------------------------------------------
def main():
"""main"""
args = get_args()
FILE = args.FILE.IGNORECASE()
if len(args) != 1:
print("Usage: files.py {}".format(FILE))
sys.exit(1)
# --------------------------------------------------
if __name__ == '__main__':
main()
Expected outcome:
$ ./files.py
Usage: files.py FILE
What I am getting:
$./files.py
$
You never run main...
import argparse
import re
#--------------------------------------------------
def get_args():
"""get arguments"""
parser = argparse.ArgumentParser(
description='Create Python script',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('FILE', help='Pass a file', type=str)
return parser.parse_args()
#--------------------------------------------------
def main():
"""main"""
args = get_args()
FILE = args.FILE.IGNORECASE()
if len(args) != 1:
print("Usage: files.py {}".format(FILE))
sys.exit(1)
main()
You need to define the entry point of your code. If you want to call this as you are describing (./files.py) you need to define the main entry point like this:
if __name__ == "__main__":
"""main"""
args = get_args()
FILE = args.FILE.IGNORECASE()
if len(args) != 1:
print("Usage: files.py {}".format(FILE))
sys.exit(1)
You have to tell your operating system that the script must be executed by Python. Add a shebang as the first line of your script:
#!/usr/bin/env python3
import argparse
...
Otherwise, you have to explicitly execute the script with Python:
python3 ./files.py
You must call your main function. A good place is at the end of the script, guarded to be run on execution only:
if __name__ == '__main__': # do not run on import
main()
This gives the desired output:
$ python3 so_script.py
usage: so_script.py [-h] FILE
so_script.py: error: the following arguments are required: FILE
Note that argparse already creates the usage and help messages for you. There is no need to create them yourself. In fact, argparse will end your script before your own usage information is run.
If you do not want to have the -h switch, pass add_help=False when creating the argument parser.
parser = argparse.ArgumentParser(
description='Create Python script',
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
add_help=False,
)
I have the Python script that works well when executing it via command line.
What I'm trying to do is to import this script to another python file and run it from there.
The problem is that the initial script requires arguments. They are defined as follows:
#file one.py
def main(*args):
import argparse
parser = argparse.ArgumentParser(description='MyApp')
parser.add_argument('-o','--output',dest='output', help='Output file image', default='output.png')
parser.add_argument('files', metavar='IMAGE', nargs='+', help='Input image file(s)')
a = parser.parse_args()
I imported this script to another file and passed arguments:
#file two.py
import one
one.main('-o file.png', 'image1.png', 'image2.png')
But although I defined input images as arguments, I still got the following error:
usage: two.py [-h] [-o OUTPUT]
IMAGE [IMAGE ...]
two.py: error: the following arguments are required: IMAGE
When calling argparse with arguments not from sys.argv you've got to call it with
parser.parse_args(args)
instead of just
parser.parse_args()
If your MAIN isn't a def / function you can simulate the args being passed in:
if __name__=='__main__':
# Set up command-line arguments
parser = ArgumentParser(description="Simple employee shift roster generator.")
parser.add_argument("constraints_file", type=FileType('r'),
help="Configuration file containing staff constraints.")
parser.add_argument("first_day", type=str,
help="Date of first day of roster (dd/mm/yy)")
parser.add_argument("last_day", type=str,
help="Date of last day of roster (dd/mm/yy)")
#Simulate the args to be expected... <--- SEE HERE!!!
argv = ["",".\constraints.txt", "1/5/13", "1/6/13"]
# Parse arguments
args = parser.parse_args(argv[1:])
If I understand Argparse correctly, the positional arguments are the required arguments that the user can specify. I need to create a positional argument with argparse where the user can specify a certain type of argument that is displayed if he/she brings up the -h option. I've tried using add_argument_group but it simply only displays a header with a description of the other arguments when you bring up the -h option.
def Main():
parser = argparse.ArgumentParser(description = __doc__, formatter_class = argparse.RawDescriptionHelpFormatter)
parser.add_argument("input_directory",help = "The input directory where all of the files reside in")
sub_parser = parser.add_argument_group('File Type')
sub_parser.add_argument(".txt",help = "The input file is a .txt file")
sub_parser.add_argument(".n12",help = "The input file is a .n12 file")
sub_parser.add_argument(".csv",help = "The input file is a .csv file")
parser.parse_args()
if __name__ == "__main__":
Main()
So when I run the script, I should specify in order to run the script. If I choose either .txt, .n12, or .csv as my argument, then the script should run. However, if the I don't specify the file type from those 3 options listed, then the script wouldn't run.
Is there an argparse function that I'm missing that can specify multiple options for a positional argument?
Use the choices= parameter to force the user to choose from a restricted set of values.
import argparse
def Main():
parser = argparse.ArgumentParser()
parser.add_argument("input_directory",help = "The input directory where all of the files reside in")
parser.add_argument("file_type", help = "File Type", choices=['.txt', '.n12', '.csv'])
ns = parser.parse_args()
print(ns)
if __name__ == "__main__":
Main()
I think you're making this too complicated. If I understand your problem correctly, you want the user to enter two arguments: a directory name and a file type. You application will accept only three values for file type. How about simply doing this:
import argparse
def Main():
parser = argparse.ArgumentParser(description = __doc__, formatter_class = argparse.RawDescriptionHelpFormatter)
parser.add_argument("input_directory", help = "The input directory where all of the files reside in")
parser.add_argument("file_type", help="One of: .txt, .n12, .csv")
args = parser.parse_args()
print(args)
if __name__ == "__main__":
Main()
... and adding application logic to reject invalid values for file type.
You access the user-entered values through the object returned by parse_args().
Use option grouping feature use add_mutually_exclusive_group() instead of add_argument_group()
import argparse
def Main():
parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument("input_directory", help="The input directory where all of the files reside in")
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument("-txt", action='store_true', help="The input file is a .txt file")
group.add_argument("-n12", action='store_true', help="The input file is a .n12 file")
group.add_argument("-csv", action='store_true', help="The input file is a .csv file")
print parser.parse_args()
if __name__ == "__main__":
Main()
Here is the current code.
import time
import collections
from modules import outputs
from modules import scrub
from modules import lookups
parser = argparse.ArgumentParser(description='AppMap Converter to Generate Asset Files from AppMapp Data')
parser.add_argument("operation", nargs='?', default="empty", help='The operation to perform')
parser.add_argument("input", nargs='?', default="empty", help='The input AppMapp File Path')
parser.add_argument("output", nargs='?', default="empty", help='The output Asset File Path')
args = parser.parse_args()
start = time.time()
if(args.operation == "Convert"):
input_file_path = args.input
output_file_path = args.output
#DO LOTS OF STUFF
else:
exit()
The script is called sacsproc, so I run it from the command line as follows:
./sacsproc Convert input.csv output.csv
This all works nicely, the problem is that I need more sacsproc commands which may have a totally different set of secondary parameters. i.e. one command might be:
./sacsproc Clean -rts input.csv output.csv err.csv
Thus, I am trying to determine how one defines arguments that are conditional on the first argument? In my mind, I'm thinking about the zfs command line utilities that do what I am trying to do (e.g. zpool create mirror sdb sdc vs. zpool remove sda).
use subparsers
subparsers = parser.add_subparsers(help="sub-command help")
group1 = subparsers.add_parser("something",help="do something")
group1.set_defaults(which="g1") # some default value (so you know which group was activated)
group1.add_argument("ARG",help='do something on ARG')
group2 = subparsers.add_parser("other",help="do something else")
group2.set_defaults(which="g2") # give some default value
group2.add_argument("ARG",help='do something else on ARG')
ok ...
import argparse
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(help="sub-command help")
g1 = subparsers.add_parser("thing1",help="bind to a port and just echo back anything it gets ... with a prompt")
g1.set_defaults(which="g1")
g1.add_argument("input",help='the input file')
g1.add_argument("output",help='the output file')
g2 = subparsers.add_parser("thing2",help="create a bridge between two ports, this is useful for generating a logfile")
g2.set_defaults(which="g2")
g2.add_argument("input",help='thie input file')
g2.add_argument("output",help='the output file')
g2.add_argument("error",help="the err file")
def print_help(args):
print "ARGS:",args
try:
parser.parse_args(args)
except:
print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n"
print_help(["-h"])
print_help(["thing1","-h"])
print_help(["thing2","-h"])