Example for setting up arguments for your command line utility.
Example Usage:
@@ -225,29 +225,35 @@ module has many more features documented at
# description and epilog. The `formatter_class` instructs# argparse to show default values set for parameters.parser=argparse.ArgumentParser(
- description='Sample Argparse',
+ description="Sample Argparse",formatter_class=argparse.ArgumentDefaultsHelpFormatter,
- epilog=f"Built by {__author__}, v.{__date__}"
+ epilog=f"Built by {__author__}, v.{__date__}",)# The simplest form of adding an argument, the name of the# parameter and a description of its form.
- parser.add_argument('INPUT_FILE',help="Input file to parse")
- parser.add_argument('OUTPUT_FOLDER',
- help="Folder to store output")
+ parser.add_argument("INPUT_FILE",help="Input file to parse")
+ parser.add_argument("OUTPUT_FOLDER",help="Folder to store output")# An optional argument with multiple methods of specifying# the parameter. Includes a default value
- parser.add_argument('-l','--log',help="Path to log file",
- default=os.path.abspath(os.path.join(
- PurePath(__file__).parent,
- PurePath(__file__).name.rsplit('.',1)[0]+'.log'))
+ parser.add_argument(
+ "-l",
+ "--log",
+ help="Path to log file",
+ default=os.path.abspath(
+ os.path.join(
+ PurePath(__file__).parent,
+ PurePath(__file__).name.rsplit(".",1)[0]+".log",
+ )
+ ),)# An optional argument which does not accept a value, instead# just modifies functionality.
- parser.add_argument('-v','--verbose',action='store_true',
- help='Include debug log messages')
+ parser.add_argument(
+ "-v","--verbose",action="store_true",help="Include debug log messages"
+ )# Once we've specified our arguments we can parse them for# reference
@@ -259,8 +265,8 @@ module has many more features documented at
Example for writing logging information to the console and a
log file.
Example Usage:
@@ -280,64 +286,82 @@ to write content to STDOUT uninterrupted. Additionally, you can
set different logging levels for the two handlers - generally you
keep debugging information in the log file while writing more
critical messages to the console in STDERR.
-
defsetup_logging():
- """Function to setup logging configuration and test it."""
- # Allow us to modify the `logger` variable within a function
- globallogger
+
defsetup_logging(logging_obj,verbose=False):
+ """Function to setup logging configuration and test it.
- # Set logger object, uses module's name
- logger=logging.getLogger(name=__name__)
+ Args:
+ logging_obj: A logging instance, returned from logging.getLogger().
+ verbose: Whether or not to enable the debug level in STDERR output.
- # Set default logger level to DEBUG. You can change this later
- logger.setLevel(logging.DEBUG)
+ Examples:
+ >>> sample_logger = logging.getLogger(name=__name__)
+ >>> sample_logger = setup_logging(sample_logger)
+ >>> sample_logger.debug("This is a debug message")
+ >>> sample_logger.info("This is an info message")
+ >>> sample_logger.warning("This is a warning message")
+ >>> sample_logger.error("This is a error message")
+ >>> sample_logger.critical("This is a critical message")
+ """
+ logging_obj.setLevel(logging.DEBUG)
- # Logging formatter. Best to keep consistent for most usecases
+ # Logging formatter. Best to keep consistent for most use caseslog_format=logging.Formatter(
- '%(asctime)s%(filename)s%(levelname)s%(module)s '
- '%(funcName)s%(lineno)d%(message)s')
+ "%(asctime)s%(filename)s%(levelname)s%(module)s "
+ "%(funcName)s%(lineno)d%(message)s"
+ )# Setup STDERR logging, allowing you uninterrupted# STDOUT redirectionstderr_handle=logging.StreamHandler(stream=sys.stderr)
- stderr_handle.setLevel(logging.INFO)
+ ifverbose:
+ stderr_handle.setLevel(logging.DEBUG)
+ else:
+ stderr_handle.setLevel(logging.INFO)stderr_handle.setFormatter(log_format)# Setup file logging
- file_handle=logging.FileHandler('sample.log','a')
+ file_handle=logging.FileHandler("sample.log","a")file_handle.setLevel(logging.DEBUG)file_handle.setFormatter(log_format)# Add handles
- logger.addHandler(stderr_handle)
- logger.addHandler(file_handle)
+ logging_obj.addHandler(stderr_handle)
+ logging_obj.addHandler(file_handle)
- # Sample log messages
- logger.debug("This is a debug message")
- logger.info("This is an info message")
- logger.warning("This is a warning message")
- logger.error("This is a error message")
- logger.critical("This is a critical message")
-
- defsample_function():
- """Sample function to demonstrate logging formatting."""
- logger.info("Called from a function")
-
- sample_function()
+ returnlogging_obj
Function to setup logging configuration and test it.
+
+
Parameters
+
+
logging_obj – A logging instance, returned from logging.getLogger().
+
verbose – Whether or not to enable the debug level in STDERR output.
+
+
+
+
Examples
+
>>> sample_logger=logging.getLogger(name=__name__)
+>>> sample_logger=setup_logging(sample_logger)
+>>> sample_logger.debug("This is a debug message")
+>>> sample_logger.info("This is an info message")
+>>> sample_logger.warning("This is a warning message")
+>>> sample_logger.error("This is a error message")
+>>> sample_logger.critical("This is a critical message")
+
Demonstrates how to handle setting the proper encoding for
UTF-8, UTF-16-LE, and UTF-16-BE with the ability to easily
@@ -364,18 +388,17 @@ common text file encodings. Feel free to build and share on this.
Demonstrates source datasets comprised of lists of dictionaries
and lists of lists as separate functions. Example data is
@@ -424,7 +447,7 @@ multiple dictionaries to a CSV file. You can optionally provide
an ordered list of headers to filter what rows to show, or let the
function use the keys of the first dictionary in the list to
generate the header information. The latter option may produce
-a new order each iteration and is not prefered if you can
+a new order each iteration and is not preferred if you can
determine the headers in advance.
defwrite_csv_dicts(outfile,data,headers=None):"""Writes a list of dictionaries to a CSV file.
@@ -434,18 +457,24 @@ determine the headers in advance.
data (list): List of dictionaries to write to file headers (list): Header row to use. If empty, will use the first dictionary in the `data` list.
+
+ Example:
+ >>> list_of_dicts = [
+ >>> {'name': 'apple', 'quantity': 10, 'location': 'VT'},
+ >>> {'name': 'orange', 'quantity': 5, 'location': 'FL'}
+ >>> ]
+ >>> write_csv_dicts('dict_test.csv', list_of_dicts) """ifnotheaders:# Use the first line of dataheaders=[str(x)forxindata[0].keys()]
- withopen(outfile,'w',newline="")asopen_file:
+ withopen(outfile,"w",newline="")asopen_file:# Write only provided headers, ignore others
- csvfile=csv.DictWriter(open_file,headers,
- extrasaction='ignore')
- csvfile.writeheader()
- csvfile.writerows(data)
+ csv_file=csv.DictWriter(open_file,headers,extrasaction="ignore")
+ csv_file.writeheader()
+ csv_file.writerows(data)
@@ -474,25 +503,33 @@ columns to the CSV.
data (list): List of lists to write to file headers (list): Header row to use. If empty, will use the first list in the `data` list.
+
+ Examples:
+ >>> fields = ['name', 'quantity', 'location']
+ >>> list_of_lists = [
+ >>> ['apple', 10, 'VT'],
+ >>> ['orange', 5, 'FL']
+ >>> ]
+ >>> write_csv_lists('list_test.csv', list_of_lists, headers=fields) """
- withopen(outfile,'w',newline="")asopen_file:
+ withopen(outfile,"w",newline="")asopen_file:# Write only provided headers, ignore others
- csvfile=csv.writer(open_file)
+ csv_file=csv.writer(open_file)forcount,entryinenumerate(data):ifcount==0andheaders:# If headers are defined, write them, otherwise# continue as they will be written anyways
- csvfile.writerow(headers)
- csvfile.writerow(entry)
+ csv_file.writerow(headers)
+ csv_file.writerow(entry)
Demonstration of iterating through a directory to interact with
files.
@@ -544,7 +598,16 @@ folders within a single directory. From here you can further
interact with individual files and folders or iterate recursively
by calling the function on identified subdirectories.
deflist_directory(path):
- """List all file and folder entries in `path`."""
+ """List all file and folder entries in `path`.
+
+ Args:
+ path (str): A directory within a mounted file system. May be relative or
+ absolute.
+
+ Examples:
+ >>> list_directory('.')
+
+ """print(f"Files and folders in '{os.path.abspath(path)}':")# Quick and easy method for listing items within a single# folder.
@@ -564,6 +627,21 @@ handling the processing of files. This sample shows a method of
counting the number of files, subdirectories, and files ending in
“.py” as an example.
defiterate_files(path):
+ """Recursively iterate over a path, findings all files within the folder
+ and its subdirectories.
+
+ Args:
+ path (str): A directory within a mounted file system. May be relative or
+ absolute.
+
+ Examples:
+ >>> number_of_py_files = 0
+ >>> for f in iterate_files('../'):
+ ... if f.endswith('.py'):
+ ... number_of_py_files += 1
+ >>> print(f"\t{number_of_py_files} python files found "
+ ... f"in {os.path.abspath('../')}")
+ """# Though `os.walk()` exposes a list of directories in the# current `root`, it is rarely used since we are generally# interested in the files found within the subdirectories.
@@ -572,19 +650,50 @@ counting the number of files, subdirectories, and files ending in
forroot,dirs,filesinos.walk(os.path.abspath(path)):# Both `dirs` and `files` are lists containing all entries# at the current `root`.
- forfentryinfiles:
+ forfile_nameinfiles:# To effectively reference a file, you should include# the below line which creates a full path reference# to the specific file, regardless of how nested it is
- file_entry=os.path.join(root,fentry)# We can then hand `file_entry` off to other functions.
- yieldfile_entry
+ yieldos.path.join(root,file_name)