En Thu, 06 Aug 2009 11:50:07 -0300, jakecjacobson <jakecjacob...@gmail.com> escribió:

After much Google searching and trial & error, I was able to write a
Python script that posts XML files to a REST API using HTTPS and
passing PEM cert & key file.  It seems to be working but would like
some pointers on how to handle errors.  I am using Python 2.4, I don't
have the capability to upgrade even though I would like to.  I am very
new to Python so help will be greatly appreciated and I hope others
can use this script.

Just a few remarks, mostly on style rather than functionality:

#!/usr/bin/python
#################################################################
# catalog_feeder.py
#################################################################
# This sciript will process a directory of XML files and push them to
the Enterprise Catalog.
#  You configure this script by using a configuration file that
describes the required variables.
#  The path to this file is either passed into the script as a command
line argument or hard coded
#  in the script.  The script will terminate with an error if it can't
process the XML file.
#################################################################

Note that Python has "docstrings" - the __doc__ attribute attached to every module, class and function. The very first string in the module/function/class becomes its docstring. The interactive help system -and other tools like pydoc- can inspect and show such info. The above comment could serve perfectly as this module's docstring - just remove all the #'s and enclose the whole text in """triple quotes""" (required as it spawns many lines). By example, in that case you could print the text in your usage() function like this:
print __doc__

        try:
                # Process the XML conf file ....
                xmldoc = minidom.parse(c)
                catalog_host = readConfFile(xmldoc, 'catalog_host')
                catalog_port = int(readConfFile(xmldoc, 'catalog_port'))
                catalog_path = readConfFile(xmldoc, 'catalog_path')
                collection_name = readConfFile(xmldoc, 'collection_name')
                cert_file = readConfFile(xmldoc, 'cert_file')
                key_file = readConfFile(xmldoc, 'key_file')
                log_file = readConfFile(xmldoc, 'log_file')
                input_dir = readConfFile(xmldoc, 'input_dir')
                archive_dir = readConfFile(xmldoc, 'archive_dir')
                hold_dir = readConfFile(xmldoc, 'hold_dir')
        except Exception, inst:
                # I had an error so report it and exit script
                print "Unexpected error opening %s: %s" % (c, inst)
                sys.exit(1)

Ok, an unexpected error: but *which* one? doing exactly *what*? You're hiding important information (the error type, the full traceback, the source line that raised the error...) that's very valuable when something goes wrong and you have to determine what happened. In this case, you're adding a bit of information: the name of the file being processed. That's good. But at the same time, hiding all the other info, and that's not so good. What about this:

        except Exception:
                print >>sys.stderr, "Unexpected error opening %s" % c
                raise

The final raise will propagate the exception; by default, Python will print the exception type, the exception value, the full traceback including source lines, and exit the script with a status code of 1. The same effect that you intended, but more complete.

In other cases, where you don't have anything to add to the default exception handling, the best thing to do is: nothing. That is, don't catch an exception unless you have something good to do with it. (Exceptions aren't Pokémon: you don't have to "catch 'em all!")

        # Log Starting
        logOut = verifyLogging(log_file)
        if logOut:
                log(logOut, "Processing Started ...")

I would move the decision into the log function (that is, just write log("something") and make the log function decide whether to write to file or not). For your next script, look at the logging module: http://docs.python.org/library/logging.html

# Get an arry of files from the input_dir
def getFiles2Post(d):
        return (os.listdir(d))

Note that return isn't a function but a statement. You don't need the outer (). Also, using a docstring instead of a comment:

def getFiles2Post(input_dir):
    "Return the list of files in input_dir to process"
    return os.listdir(input_dir)

# Read out the conf file and set the needed global variable
def readConfFile(xmldoc, tag):
        return (xmldoc.getElementsByTagName(tag)[0].firstChild.data)

Same as above. Which "needed global variable"?

def cleanup(logOut):
      [...]     sys.exit(0)

Exiting the script from everywhere makes it harder to reuse some of its functions later. Just return the desired status code to the caller, which in turn will return to main(), until it gets to the outermost level, which is the only place I'd use sys.exit()

--
Gabriel Genellina

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to