I need to rewrite an arguments parser.The application has two modes: console and graphics. We can choose only one mode. Lately, the console version received two arguments: name of file with text and name of file with words. It looked so:
def parse_args():
parser = argparse.ArgumentParser(description='Fuzzy search in text')
parser.add_argument('-g', '--graphics', help='graphical version',
action='store_true')
parser.add_argument('-c', '--console', help='console version', nargs=2,
type=argparse.FileType('r'),
metavar=('TEXTFILE', 'WORDSFILE'))
return parser.parse_args()
usage: fuzzy_search.py [-h] [-g] [-c TEXTFILE WORDSFILE]
Fuzzy search in text
optional arguments:
-h, --help show this help message and exit
-g, --graphics graphical version
-c TEXTFILE WORDSFILE, --console TEXTFILE WORDSFILE
console version
Now I need to rewrite the accepting of arguments in the console version. I want to add two optional arguments that will store true for register-sensitivity (-r) and special view(-v). I know how to do it but I can't understand what to do with the next thing. I want to make two variants: 1)obligatory two files with text and words like it was initially and 2) obligatory file with text and not obligatory file with words, if it's not written than default - sys.stdin. Graphics shouldn't accept any arguments. So it should look like this
usage: fuzzy_search.py [-h] [-g] [-c [-r] [-v] TEXTFILE WORDSFILE(if not written then sys.stdin)]
I tried this variant:
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(help='versions')
parser_console = subparsers.add_parser('console', help='console version')
parser_console.add_argument('-r', '--register-check', action='store_true', help='register sensitivity')
parser_console.add_argument('-v', '--row-view', action='store_true', help='row view')
parser_console.add_argument('TEXTFILE', type=argparse.FileType('r'), help='text file')
parser_console.add_argument('--WORDSFILE', type=argparse.FileType('r'), default=sys.stdin, help='words file')
parser_graphics = subparsers.add_parser('graphics', help='graphics version')
But when I tried this
print(parser.parse_args(['console', '-r', '-v', 'text.txt','words.txt']))
there was an error:
unrecognized arguments: words.txt
with this
print(parser.parse_args(['console', '-r', '-v', 'text.txt']))
everything is ok:
Namespace(TEXTFILE=<_io.TextIOWrapper name='text.txt' mode='r' encoding='cp1251'>, WORDSFILE=<_io.TextIOWrapper name='<stdin>' mode='r' encoding='UTF-8'>, register_check=True, row_view=True)
So problem somewhere in optional argument WORDSFILE and its default value. How to correct it?
Use -t for text and -w for the words file. The latter with default:
import argparse
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(help='versions')
parser_console = subparsers.add_parser('console',
help='console version')
parser_console.add_argument('-r', '--register-check',
action='store_true', help='register sensitivity')
parser_console.add_argument('-v', '--row-view',
action='store_true', help='row view')
parser_console.add_argument('-t', '--textfile',
type=argparse.FileType('r'),
help='text file')
parser_console.add_argument('-w', '--wordsfile', type=argparse.FileType('r'),
default=sys.stdin, help='words file')
print(parser.parse_args(['console', '-r', '-v', '-t', 'text.txt',
'-w', 'words.txt']))
parser.parse_args(['console', '-r', '-v', '-t', 'text.txt'])
Output:
Namespace(register_check=True, row_view=True,
textfile=<_io.TextIOWrapper name='text.txt' mode='r' encoding='UTF-8'>,
wordsfile=<_io.TextIOWrapper name='words.txt' mode='r' encoding='UTF-8'>)
Namespace(register_check=True, row_view=True,
textfile=<_io.TextIOWrapper name='text.txt' mode='r' encoding='UTF-8'>,
wordsfile=<_io.TextIOWrapper name='<stdin>' mode='r' encoding='UTF-8'>)
Related
I have tried the below code
def parse_args():
"""Get user command line parameters"""
parser = argparse.ArgumentParser(description="Available Options")
parser.add_argument('-i', '--input-path', type=is_valid_path,
required=True, help="Enter the path of the file or the folder to process")
parser.add_argument('-a', '--action', choices=[
'Highlight', 'Redact'], type=str, help="Choose to highlight or to redact")
parser.add_argument('-s', '--search-str', dest='search_str',
type=str, help="Enter a valid search string")
parser.add_argument('-p', '--pages', dest='pages', type=tuple,
help="Enter the pages to consider in the PDF file, e.g. (0,1)")
parser.add_argument("-g", "--generate-output", action="store_true", help="Generate text content in a CSV file")
path = parser.parse_known_args()[0].input_path
if os.path.isfile(path):
parser.add_argument('-o', '--output_file', dest='output_file',
type=str, help="Enter a valid output file")
parser.add_argument("-t", "--highlight-readable-text", action="store_true", help="Highlight readable text in the generated image")
parser.add_argument("-c", "--show-comparison", action="store_true", help="Show comparison between captured image and the generated image")
if os.path.isdir(path):
parser.add_argument("-r", "--recursive", action="store_true", help="Whether to process the directory recursively")
# To Porse The Command Line Arguments
args = vars(parser.parse_args())
# To Display The Command Line Arguments
print("## Command Arguments #################################################")
print("\n".join("{}:{}".format(i, j) for i, j in args.items()))
print("######################################################################")
return args
if name == 'main':
args = parse_args()
# If File Path
if os.path.isfile(args['input_path']):
# Process a file
if filetype.is_image(args['input_path']):
ocr_img(
# if 'search_str' in (args.keys()) else None
img=None, input_file=args['input_path'], search_str=args['search_str'], highlight_readable_text=args['highlight_readable_text'], action=args['action'], show_comparison=args['show_comparison'], generate_output=args['generate_output']
)
else:
ocr_file(
input_file=args['input_path'], output_file=args['output_file'], search_str=args['search_str'] if 'search_str' in (args.keys()) else None, pages=args['pages'], highlight_readable_text=args['highlight_readable_text'], action=args['action'], show_comparison=args['show_comparison'], generate_output=args['generate_output']
)
# If Folder Path
elif os.path.isdir(args['input_path']):
# Process a folder
ocr_folder(
input_folder=args['input_path'], recursive=args['recursive'], search_str=args['search_str'] if 'search_str' in (args.keys()) else None, pages=args['pages'], action=args['action'], generate_output=args['generate_output']
)
Getting this error
usage: ipykernel_launcher.py [-h] -i INPUT_PATH [-a {Highlight,Redact}]
[-s SEARCH_STR] [-p PAGES] [-g]
ipykernel_launcher.py: error: the following arguments are required: -i/--input-path
An exception has occurred, use %tb to see the full traceback.
SystemExit: 2
C:\Users\poddaral\AppData\Roaming\Python\Python310\site-packages\IPython\core\interactiveshell.py:3386: UserWarning: To exit: use 'exit', 'quit', or Ctrl-D.
warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)
You need to paas input path as an argument while running the code. Let's say file name is abc.py, then in command line run
python abc.py --input_path Path
import argparse
import logging
handlers = [logging.FileHandler('logger.log',mode='a'), logging.StreamHandler() ]
logging.basicConfig( level=logging.DEBUG,format='[%(levelname)s] %(message)s' ,handlers = handlers )
parser = argparse.ArgumentParser();
parser = argparse.ArgumentParser(description="./script.py --db <db path> --scratch <scratch path> ")
required_args = parser.add_argument_group('required arguments')
required_args.add_argument('--db' , '-d', type=str, help='db directory name. Default is release',required=True)
required_args.add_argument('--scratch', '-s', type=str, help='Scratch path where report will be written')
try:
args = parser.parse_args()
except SystemExit as se:
logging.fatal("Invalid Command line argument:" )
My code is something like the above. I want to capture invalid exception arguments into the logger at the last line where I am capturing the exception. In precise whatever the message argparse is printing on stdout for any invalid arguments, I want to redirect all of them to my logger. Can you please let me how can I do it?
I want to create a script that takes two arguments that should be consumed:
directory_path,
files -- the list of files under the directory_path argument.
I've written something like that:
#!/usr/bin/python3
import argparse
import os
import argcomplete
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument("directory_path",
help="a path to some directory",
nargs=1)
# conditional choices of an argument
conditional_choices = [os.listdir(parser.parse_known_args()[0].directory_path[0])]
parser.add_argument("files",
metavar="FILES",
nargs='+',
choices=conditional_choices)
argcomplete.autocomplete(parser)
args = parser.parse_args()
print("directory_path {}".format(args.directory_path))
print("files {}".format(args.files))
So the files argument depends on the directory_path argument.
Using: Python3.8
Problems
For the above snippet, the bash-completion (built from register-python-argcomplete3) for a files argument doesn't work.
If I push enter after the valid command (with path and file) then I'm getting an error
error: argument FILES: invalid choice: ...
First is worth step in argcomplete documentation based on which I created a solution
#!/usr/bin/python3
# PYTHON_ARGCOMPLETE_OK
import argparse
import os
import argcomplete
def files_names(prefix, parsed_args, **kwargs):
absolute_pat = os.path.abspath(parsed_args.directory_path[0])
files = [file for file in os.listdir(absolute_pat) if os.path.isfile(os.path.join(absolute_pat, file))]
return files
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument("directory_path",
help="a path to some directory",
nargs=1)
parser.add_argument("files",
metavar="FILES",
nargs='+').completer = files_names
argcomplete.autocomplete(parser)
args = parser.parse_args()
print("directory_path {}".format(args.directory_path))
print("files {}".format(args.files))
*usesfull snippet from argcomplete test directory
To debugging the completion you can set the _ARC_DEBUG variable in your shell to enable verbose debug output
Here is the code.
def main():
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
description="infomedia"
)
parser.add_argument("file", help="path to file")
parser.add_argument(
"-i",
"--info",
type=str,
default="False",
help="get information about",
)
cli_args = parser.parse_args()
worker = Worker(
cli_args.input,
cli_args.info,
)
worker._application()
When the program is running with -h / --help it shows the default values.
positional arguments:
file path to file
optional arguments:
-h, --help show this help message and exit
-i INFO, --info INFO get information about (default: False)
How to avoid printing the default values? Or is there a way to define the default values of this code in a different way?
You can create new class inheriting from argparse.ArgumentDefaultsHelpFormatter and override _get_help_string method and pass your newly created class which is MyHelpFormatter in the below example as formatter_class in ArgumentParser constructor. Here is the example code which can help you:
import argparse
class MyHelpFormatter(argparse.ArgumentDefaultsHelpFormatter):
def _get_help_string(self, action):
return action.help
def main():
parser = argparse.ArgumentParser(
formatter_class=MyHelpFormatter,
description="infomedia",
)
parser.add_argument("file", help="path to file")
parser.add_argument(
"-i",
"--info",
type=str,
default="False",
help="get information about",
)
cli_args = parser.parse_args()
if __name__ == "__main__":
main()
I think you want more like:
parser.add_argument("--info", help="get information", action="store_true")
I'm running Python 3.6.8 :: Anaconda custom (64-bit) and getting strange results from argparse. Despite the -x, the value of trainandexecute=False
def get_parameters():
startup = '-x -b'
sys.argv = startup.split(' ')
ap = argparse.ArgumentParser()
ap.add_argument('-x', '--trainandexecute', action='store_true')
ap.add_argument('-b', '--debug', action='store_true')
ap.add_argument('-d', '--rundate', action='store')
print(ap.parse_args())
return vars(ap.parse_args())
get_parameters()
This returns the following output. Notet that trainandexecute=False despite the -x flag.
Namespace(debug=True, execute=False, train=False, trainandexecute=False)
{'train': False,
'execute': False,
'trainandexecute': False,
'debug': True}
However, this test works in the next Jupyter cell and that it is not my environment:
def get_test_parameters():
startup = '-b -x'
sys.argv = startup.split(' ')
print(sys.argv)
ap = argparse.ArgumentParser()
ap.add_argument('-x', '--x', action='store_true')
ap.add_argument('-b', '--debug', action='store_true')
print(ap.parse_args())
return vars(ap.parse_args())
So the output of:
get_test_parameters()
is:
['-b', '-x'] # print(sys.argv)
Namespace(debug=False, x=True) # print(ap.parse_args())
{'x': True, 'debug': False} # return vars(ap.parse_args())
I'm bifflesnickered...
Your error is in this line:
sys.argv = startup.split(' ')
The first value in sys.argv is treated as the name of the script, not as an option. Try running ap.parse_args(startup.split()) - and you will see the right answer.
Incidentally, do not pass any parameters to split(). If you pass " " and you have more than one consecutive space, the result of the split will have empty strings.
Here's a better test framework:
def get_parameters(argv=None):
ap = argparse.ArgumentParser()
ap.add_argument('-x', '--trainandexecute', action='store_true')
ap.add_argument('-b', '--debug', action='store_true')
ap.add_argument('-d', '--rundate', action='store')
args = ap.parse_args(argv)) # if None, parses sys.argv[1:]
print(args)
return vars(args)
get_parameters('-x -b'.split())
You can modify sys.argv[1:] instead. By passing argv through your function, you can test several ways.