I am using argparse to require input from the user for a hardware id to then be called later on, I cannot work out how to get it so the user types
<command> --id <id>
Please help me see where I'm going wrong! Thanks
parser = argparse.ArgumentParser(description='Return a list of useful information after specifying a hardare/asset ID')
parser.add_argument('--id', type=str, required=True, help ='A hardware/asset id to provide information on')
args = vars(parser.parse_args())
args = parser.parse_args()
def main():
hardware_id = hardware_id_input
host = get_host_information(hardware_id)
print(host["hostname"])
print(host["hardware_id"])
Ditch the call to vars. You would have your argument stored as args.id after parsing. You would then call your main with the args.id as input.
Edit: added a code sample
def main(hw_id):
print(hw_id)
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description='Description.')
parser.add_argument('--id', type=str, help='The hardware id.', required=True)
args = parser.parse_args()
main(args.id)
Related
BSD
hi guys, i wrote a program that takes arguments with argparse and the stores it in variables,
then the variables contents is used to be passed out to an XML file that i want to create;
gere is a snippet from my code:
import argparse
from lxml import etree
if __name__ == '__main__':
my_parser = argparse.ArgumentParser()
my_parser.add_argument('U', type=str, action='store', help='Enter the account user name')
my_parser.add_argument('P', type=str, action='store', help='Enter the account password')
my_parser.add_argument('i', type=str, action='store', help='Enter the phone Number To Send
the SMS')
my_parser.add_argument('k', type=str, action='store', help='Enter the senders phone
number')
my_parser.add_argument('data', type=str, action='store', help='Enter the text for SMS')
my_parser.add_argument('e', type=str, action='store', help='send sms?')
args = my_parser.parse_args()
username = args.U
password = args.P
phone = args.i
reply = args.k
data = args.data
#print(args.U, args.P, args.i, args.k, args.data)
if args.e:
# Create the root element
page = etree.Element('sms')
# Make a new document tree
doc = etree.ElementTree(page)
# Add the subelements
pageElement1 = etree.SubElement(page, 'Account')
subelement2 = etree.SubElement(pageElement1, 'id').text = username
subelement3 = etree.SubElement(pageElement1, 'password').text = password
# Add the subelements for "Attributes" tree
pageElement2 = etree.SubElement(page, 'Attributes')
subelement4 = etree.SubElement(pageElement2, 'reference').text = '123'
subelement5 = etree.SubElement(pageElement2, 'replyPath').text = reply
# Save to XML file
doc.write('output.xml', xml_declaration=True, encoding='utf-8')
when i run it from the CMD, it runs only the first part, but the XML part is not executed.
can someone plz help?
thanks
The issue according to me is when you are running the command you are not sending value from command prompt for e. Try using following command:-
python your_filename.py e="your value"
or you can also use following command:-
python your_filename.py --e "your value"
And print out the value of args.e
I am in the bit of a weird situation where I need a Python function to run from within a script, with the script then called from my main code.
I wanted to use the subprocess module, and know how to use it to pass arguments to a pure script, but the thing is, I need to pass the arguments to the nested Python function within, most of which are optional and have default values.
I thought arparse would help me do this somehow.
Here is an example of what I am trying:
## Some Argparse, which will hopefully help
import argparse
parser = argparse.ArgumentParser()
## All arguments, with only "follow" being required
parser.add_argument('file_name', help='Name of resulting csv file')
parser.add_argument('sub_name', help='Sub-name of resulting csv file')
parser.add_argument('follow', help='Account(s) to follow', required=True)
parser.add_argument('locations', help='Locations')
parser.add_argument('languages', help='Languages')
parser.add_argument('time_limit', help='How long to keep stream open')
args = parser.parse_args()
## Actual Function
def twitter_stream_listener(file_name=None,
sub_name='stream_',
auth = api.auth,
filter_track=None,
follow=None,
locations=None,
languages=None,
time_limit=20):
... function code ...
... more function code ...
...
...
## End of script
If you are passing arguments to functions all you need to do is feed them into the function when you're executing them:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-o", "--output_file_name", help="Name of resulting csv file")
parser.add_argument("-s", "--sub_name", default="stream_", help="Sub-name of resulting csv file")
parser.add_argument("-f", "--follow", help="Account(s) to follow", required=True)
parser.add_argument("-loc", "--locations", default=None, help="Locations")
parser.add_argument("-lan", "--languages", default=None, help="Languages")
parser.add_argument("-t", "--time_limit", default=20, help="How long to keep stream open")
options = parser.parse_args()
# then just pass in the arguments when you run the function
twitter_stream_listener(file_name=options.output_file_name,
sub_name=options.sub_name,
auth=api.auth,
filter_track=None,
follow=options.follow,
locations=options.locations,
languages=options.languages,
time_limit=options.time_limit)
# or, pass the arguments into the functions when defining your function
def twitter_stream_listener_with_args(file_name=options.output_file_name,
sub_name=options.sub_name,
auth=api.auth,
filter_track=None,
follow=options.follow,
locations=options.locations,
languages=options.languages,
time_limit=options.time_limit):
# does something
pass
# then run with default parameters
twitter_stream_listener_with_args()
You can specify defaults in the argparse section (if that is what you are trying to achieve):
#!/usr/bin/python
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--argument', default = 'something', type = str, help = 'not helpful')
parser.add_argument('--arg2', default = None, type = str, help = 'not helpful')
args = parser.parse_args()
def foo(arg , arg2 ):
print(arg)
if not arg2 is None:
print(arg2)
foo(args.argument, args.arg2)
Then calling:
$ ./test.py
something
$ ./test.py --argument='somethingelse'
somethingelse
$ ./test.py --arg2=123
something
123
$ ./test.py --arg2='ipsum' --argument='lorem'
lorem
ipsum
Is this helpful?
You can do it like that:
import argparse
## Actual Function
def twitter_stream_listener(file_name=None,
sub_name='stream_',
auth=api.auth,
filter_track=None,
follow=None,
locations=None,
languages=None,
time_limit=20):
# Your content here
if __name__ == '__main__':
parser = argparse.ArgumentParser()
## All arguments, with only "follow" being required
parser.add_argument('follow', help='Account(s) to follow')
parser.add_argument('--file_name', help='Name of resulting csv file')
parser.add_argument('--sub_name', help='Sub-name of resulting csv file')
parser.add_argument('--locations', help='Locations')
parser.add_argument('--languages', help='Languages')
parser.add_argument('--time_limit', help='How long to keep stream open')
args = parser.parse_args()
twitter_stream_listener(file_name=args.file_name, sub_name=args.sub_name, follow=args.follow,
locations=args.locations, languages=args.languages, time_limit=args.time_limit)
follow will be the only required argument and the rest optional. Optional ones have to be provided with -- at the beginning. You can easily use the module with subprocess if you need it.
Example call using command line:
python -m your_module_name follow_val --file_name sth1 --locations sth2
community,
I am trying to parse arguments as default values for principal credentials on Azure using Python CLI. In my code, I am trying to hardcode the default values for the "--azure-client-id", "--azure-secret", "--azure-tenant" and "--azure-subscription-id" as default but I am not 100% how to add it. I have been searching all over the net but can't find the answer as yet
I am still learning and I was hoping that someone could help me.
Thank you in advances for your help
My code below
def parse_args(args):
'''parse arguments from command line'''
variables = {}
parser = argparse.ArgumentParser()
parser.add_argument("action",
help="the command to be action",
choices=["delete", "create"],
nargs='?',
default="set")
parser.add_argument("-f", "--folder",
dest="folder",
nargs='?',
help="folder container ARM template & parameters json",
metavar="FOLDER")
parser.add_argument("-b",
"--build-number",
dest="build_number",
help="build number of the resource number")
parser.add_argument("-c",
"--azure-client-id",
dest="azure_client_id",
help="azure client id")
parser.add_argument("-s",
"--azure-secret",
dest="azure_secret",
help="azure secret")
parser.add_argument("-t",
"--azure-tenant",
dest="azure_tenant",
help="azure tenant")
parser.add_argument("-sid",
"--azure-subscription-id",
dest="azure_subscription_id",
help="azure subscription id")
args = parser.parse_args(args)
parser.add_argument('--azure-client-id', nargs='?', const='ID',
default='ID')
nargs='?' = 0 or 1 arguments
const='ID' = sets default value when no arguments are passed
default='ID' = if '--azure-client-id' is not specified this will be the default value
https://docs.python.org/3/library/argparse.html#nargs
I cant see m to figure out how to iterate over the accepted args of argparse. I get I can iterate over the parsed_args result, but what I want is to iterate over the arguments the parser is configured with ( ie with optparse you can iterate over the args ).
for example:
parser = argparse.ArgumentParser( prog = 'myapp' )
parser.add_argument( '--a', .. )
parser.add_argument( '--b', ...)
parser.add_argument( '--c', ... )
for arg in parser.args():
print arg
would result in
--a
--b
--c
You'll probably want to getattr from the args:
args = parser.parse_args()
for arg in vars(args):
print arg, getattr(args, arg)
Result:
a None
c None
b None
If you want to list the optionals you can do it this way:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo')
parser.add_argument('--bar')
parser.add_argument('--baz')
for option in parser._optionals._actions:
print(option.option_strings)
I don't see a practical reason to iterate over them however. You can always see the options via --help.
A bit late to the game here, but I found a way to do this without reading from private variables by using a custom help formatter that collects the arguments it is asked to format.
The following program will print ['-h', '--help', '--a', '--b', '--c']
import argparse
class ArgCollector(argparse.HelpFormatter):
# Will store the arguments in a class variable since argparse uses a class
# name, not an instance of a class
args = []
def add_argument(self, action):
# Just remember the options
self.args.extend(action.option_strings)
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--a')
parser.add_argument('--b')
parser.add_argument('--c')
# Install our new help formatter, use it, then restore the original
# formatter
original_formatter_class = parser.formatter_class
parser.formatter_class = ArgCollector
parser.format_help()
parser.formatter_class = original_formatter_class
# Print the args that argparse would accept
print(ArgCollector.args)
if __name__ == '__main__':
main()
I have tons of variables and argument definitions. Is there a way to make this take up less lines, or am I stuck with it?
# Standard input module to absorb commands from CLI
parser = argparse.ArgumentParser(description='User inputs source and destination tables to transfer data.')
parser.add_argument('src_table', help='Source table not supplied.', type=str)
parser.add_argument('dest_table', help='Destination table not supplied.', nargs='?', type=str) # optional arg
parser.add_argument('instance_object', help='New item not supplied.', nargs='?', type=str)
parser.add_argument('instance_id', help='Item ID not supplied.', nargs='?', type=int)
args = parser.parse_args()
src_table = args.src_table
dest_table = args.dest_table
Resist the urge to create tons of variables. Access the values through args instead.
However, it is possible to convert all the attributes of args into global variables:
globals().update(**vars(args))
but this pollutes the global namespace.
A better option is to pass the args to a function:
def main(src_table, dest_table, instance_object, instance_id):
print(src_table, dest_table, instance_object, instance_id)
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser(description='User inputs source and destination tables to transfer data.')
parser.add_argument('src_table', help='Source table not supplied.', type=str)
parser.add_argument('dest_table', help='Destination table not supplied.', nargs='?', type=str) # optional arg
parser.add_argument('instance_object', help='New item not supplied.', nargs='?', type=str)
parser.add_argument('instance_id', help='Item ID not supplied.', nargs='?', type=int)
args = parser.parse_args()
main(**vars(args))
Thus, inside of main, all of arg's attributes will be accessible as local variables. Structuring your program this way allows your code to be used as both a script and be importable as a module. This makes your code more versatile, and is thus much nicer than "polluting" the global namespace with lots of variables.