Help making this script better

jakecjacobson jakecjacobson at gmail.com
Thu Aug 6 16:50:07 CEST 2009


Hi,

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.

#!/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.
#################################################################

# IMPORT STATEMENTS
import httplib
import mimetypes
import os
import sys
import shutil
import time
from urllib import *
from time import strftime
from xml.dom import minidom

def main(c):
	start_time = time.time()
	# Set configuration parameters
	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)
	# Log Starting
	logOut = verifyLogging(log_file)
	if logOut:
		log(logOut, "Processing Started ...")
	# Get list of XML files to process
	if os.path.exists(input_dir):
		files = getFiles2Post(input_dir)
	else:
		if logOut:
			log(logOut, "WARNING!!! Couldn't find input directory: " +
input_dir)
			cleanup(logOut)
		else:
			print "Dir doen't exist: " + input_dir
			sys.exit(1)
	try:
		# Process each file to the catalog
		connection = httplib.HTTPSConnection(catalog_host, catalog_port,
key_file, cert_file)
		for file in files:
			log(logOut, "Processing " + file + " ...")
			try:
				response = post2Catalog(connection, catalog_path, os.path.join
(input_dir, file), collection_name)
				if response.status == 200:
					msg = "Succesfully posted " +  file + " to cataloge ..."
					print msg
					log(logOut, msg)
					# Move file to done directory
					shutil.move(os.path.join(input_dir, file), os.path.join
(archive_dir, file))
				else:
					msg = "Error posting " +  file + " to cataloge [" + response.read
() + "] ..."
					print msg
					log(logOut, response.read())
					# Move file to error dir
					shutil.move(os.path.join(input_dir, file), os.path.join(hold_dir,
file))
			except IOError, (errno):
				print "%s" % (errno)

	except httplib.HTTPException, (e):
		print "Unexpected error %s " % (e)

	run_time = time.time() - start_time
	print 'Run time: %f seconds' % run_time

	# Clean up
	connection.close()
	cleanup(logOut)

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

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

# Write out the message to log file
def log(f, m):
	f.write(strftime("%Y-%m-%d %H:%M:%S") + " : " + m + '\n')

# Clean up and exit
def cleanup(logOut):
	if logOut:
		log(logOut, "Processing Ended ...\n")
		logOut.close()
	sys.exit(0)

# Verify if we can write to the log file and return a file handle if
we can
def verifyLogging(l):
	fh=''  # No logging default behavior
	if os.path.exists(os.path.dirname(l)):
		fh = open(l, 'a')
	return(fh)

# Print out the usage of this script
def printusage():
	print""
	print
"**************************************************************************************************"
	print " Must provide the path to the configuration file when calling
this script ..."
	print " Example: " + sys.argv[0] + " /path_2_configuration_file/
conf.xml"
	print
"**************************************************************************************************"
	print ""
	sys.exit(1)

#############################
# Posting XML file to the Catelog Service
#############################
def post2Catalog(connection, path, file, collection):
	head = {"Content-Type" : "application/x-www-form-urlencoded",
"Accept" : "text/plain"}
	parameters = urlencode({"collection" : collection, "entryxml" : open
(file,'r').read()})
	connection.request('POST', path, parameters, head)
	response = connection.getresponse()
	# To reuse the connection, I have to read the response.  I really
don't care about it so I do nothing with it.
	body = response.read()
	return response

# Main
if __name__ == "__main__":
	_pathname = os.path.dirname(sys.argv[0])
	total=len(sys.argv)
	if len(sys.argv) > 1:
		main(sys.argv[1])
	else:
		printusage()



More information about the Python-list mailing list