patternpythonMinor
Checking if CLI arguments are valid files/directories in Python
Viewed 0 times
argumentsarecheckingfilesclivalidpythondirectories
Problem
I frequently write Python scripts that require three command line arguments:
I found myself copying/pasting two functions all the time:
Questions
Code
Here is the code for
Here is the code for
config_file— A CSV configuration file
input_dir— The directory containing the input files to be processed
output_dir— The directory where the output files should be stored
I found myself copying/pasting two functions all the time:
is_valid_file and is_valid_directory.Questions
- How can I consolidate the
is_valid_fileandis_valid_directoryfunctions to eliminate duplicate code?
- Is there a better way to check that files/directories provided in CLI arguments actually exist?
Code
Here is the code for
process_the_data.py:if __name__ == "__main__":
# Process the arguments
import argparse
import arghelper
parser = argparse.ArgumentParser(
description='Process the data.')
parser.add_argument(
'config_file',
help='CSV configuration file.',
metavar='FILE', type=lambda x: arghelper.is_valid_file(parser, x))
parser.add_argument(
'input_dir',
help='Directory containing the input files.',
metavar='DIR', type=lambda x: arghelper.is_valid_directory(parser, x))
parser.add_argument(
'output_dir',
help='Directory where the output files should be saved.',
metavar='DIR', type=lambda x: arghelper.is_valid_directory(parser, x))
args = parser.parse_args()Here is the code for
arghelper.py:import os
def is_valid_file(parser, arg):
if not os.path.isfile(arg):
parser.error('The file {} does not exist!'.format(arg))
else:
# File exists so return the filename
return arg
def is_valid_directory(parser, arg):
if not os.path.isdir(arg):
parser.error('The directory {} does not exist!'.format(arg))
else:
# File exists so return the directory
return argSolution
You can address some of this by subclassing ArgumentParser. This will allow you hide the lambda calls that may turn off some and leave you scratching your head if you come back to that file later.
Your Script
New ArgHelper
Your Script
if __name__ == "__main__":
# Process the arguments
#import argparse
import arghelper
parser = arghelper.FileArgumentParser(
description='Process the data.')
parser.add_argument_with_check(
'config_file',
help='CSV configuration file.',
metavar='FILE')
parser.add_argument_with_check(
'input_dir',
help='Directory containing the input files.',
metavar='DIR')
parser.add_argument_with_check(
'output_dir',
help='Directory where the output files should be saved.',
metavar='DIR')
args = parser.parse_args()
print argsNew ArgHelper
import argparse
import os
class FileArgumentParser(argparse.ArgumentParser):
def __is_valid_file(self, parser, arg):
if not os.path.isfile(arg):
parser.error('The file {} does not exist!'.format(arg))
else:
# File exists so return the filename
return arg
def __is_valid_directory(self, parser, arg):
if not os.path.isdir(arg):
parser.error('The directory {} does not exist!'.format(arg))
else:
# File exists so return the directory
return arg
def add_argument_with_check(self, *args, **kwargs):
# Look for your FILE or DIR settings
if 'metavar' in kwargs and 'type' not in kwargs:
if kwargs['metavar'] is 'FILE':
type=lambda x: self.__is_valid_file(self, x)
kwargs['type'] = type
elif kwargs['metavar'] is 'DIR':
type=lambda x: self.__is_valid_directory(self, x)
kwargs['type'] = type
self.add_argument(*args, **kwargs)Code Snippets
if __name__ == "__main__":
# Process the arguments
#import argparse
import arghelper
parser = arghelper.FileArgumentParser(
description='Process the data.')
parser.add_argument_with_check(
'config_file',
help='CSV configuration file.',
metavar='FILE')
parser.add_argument_with_check(
'input_dir',
help='Directory containing the input files.',
metavar='DIR')
parser.add_argument_with_check(
'output_dir',
help='Directory where the output files should be saved.',
metavar='DIR')
args = parser.parse_args()
print argsimport argparse
import os
class FileArgumentParser(argparse.ArgumentParser):
def __is_valid_file(self, parser, arg):
if not os.path.isfile(arg):
parser.error('The file {} does not exist!'.format(arg))
else:
# File exists so return the filename
return arg
def __is_valid_directory(self, parser, arg):
if not os.path.isdir(arg):
parser.error('The directory {} does not exist!'.format(arg))
else:
# File exists so return the directory
return arg
def add_argument_with_check(self, *args, **kwargs):
# Look for your FILE or DIR settings
if 'metavar' in kwargs and 'type' not in kwargs:
if kwargs['metavar'] is 'FILE':
type=lambda x: self.__is_valid_file(self, x)
kwargs['type'] = type
elif kwargs['metavar'] is 'DIR':
type=lambda x: self.__is_valid_directory(self, x)
kwargs['type'] = type
self.add_argument(*args, **kwargs)Context
StackExchange Code Review Q#28608, answer score: 4
Revisions (0)
No revisions yet.