This page describes the remote Python API, and gives some examples of using this API. These examples have been tested on both Windows and Linux, and require only access to the internet and python 2.3 to run. It is available for download here.
The basic object in the remote Python API is MadrigalData, which requires the url of the home page on any Madrigal 2.3 (or above) site as an argument. This API is fully documented here.
Two applications written with the remote Python API follow. The first is a simple regression test that is run to test web services when Madrigal is installed. The second is a command line version of global searching called globalIsprint.
Simple regression test
This simple script calls the following MadrigalData methods:
import madrigalWeb
import sys
import string
import difflib
if len(sys.argv) < 2:
print 'usage: python testMadrigalWebServices.py <madrigal main url>'
sys.exit(-1)
madrigalUrl = sys.argv[1]
outFile = open('testMadrigalWebServices.out', 'w')
# create the main object to get all needed info from Madrigal
testData = madrigalWeb.MadrigalData(madrigalUrl)
instList = testData.getAllInstruments()
# print out Millstone
for inst in instList:
if inst.code == 30:
outFile.write(str(inst) + '\n')
expList = testData.getExperiments(30, 1998,1,19,0,0,0,1998,1,22,0,0,0)
for exp in expList:
# should be only one
outFile.write(str(exp) + '\n')
fileList = testData.getExperimentFiles(expList[0].id)
for file in fileList:
if string.find(file.name, 'mil980120g.002') != -1:
outFile.write(str(file) + '\n')
thisFilename = file.name
break
outFile.write(testData.isprint(thisFilename,
'gdalt,ti',
'filter=gdalt,500,600 filter=ti,1900,2000'))
outFile.write('\n')
result = testData.madCalculator(1999,2,15,12,30,0,45,55,5,-170,-150,10,200,200,0,'bmag,bn')
for line in result:
for value in line:
outFile.write('%8.2e ' % (value))
outFile.write('\n')
outFile.write('\n')
outFile.close()
globalIsprint
The globalIsprint command line application accepts a number of filters used to select which experiments/files/data to return. It calls the MadrigalData methods getInstrumentList, getExperiments, and getExperimentFiles to determine which files it needs to analyze. It then calls the MadrigalData method isprint to analyze each file.
# parse command line
arglist = ''
longarglist = ['url=',
'parms=',
'output=',
'startDate=',
'endDate=',
'inst=',
'kindat=',
'filter=',
'seasonalStartDate=',
'seasonalEndDate=',
'showFiles',
'showSummary',
'missing=',
'assumed=',
'knownbad=',
'verbose']
optlist, args = getopt.getopt(sys.argv[1:], arglist, longarglist)
# set default values
url = None
parms = None
output = None
startDate = None
endDate = None
inst = '0'
kindat = '0'
filterList = [] # since more than one allowed
seasonalStartDate = '01/01'
seasonalEndDate = '12/31'
showFiles = 0
showSummary = 0
missing = 'missing'
assumed = 'assumed'
knownbad = 'knownbad'
verbose = 0
# check if none passed in
if len(optlist) == 0:
print usage
sys.exit(0)
for opt in optlist:
if opt[0] == '--url':
url = opt[1]
elif opt[0] == '--parms':
parms = opt[1]
elif opt[0] == '--output':
output = opt[1]
elif opt[0] == '--startDate':
startDate = opt[1]
elif opt[0] == '--endDate':
endDate = opt[1]
elif opt[0] == '--inst':
inst = opt[1]
elif opt[0] == '--kindat':
kindat = opt[1]
elif opt[0] == '--filter':
filterList.append(opt[1])
elif opt[0] == '--seasonalStartDate':
seasonalStartDate = opt[1]
elif opt[0] == '--seasonalEndDate':
seasonalEndDate = opt[1]
elif opt[0] == '--showFiles':
showFiles = 1
elif opt[0] == '--showSummary':
showSummary = 1
elif opt[0] == '--missing':
missing = opt[1]
elif opt[0] == '--assumed':
assumed = opt[1]
elif opt[0] == '--knownbad':
knownbad = opt[1]
elif opt[0] == '--verbose':
verbose = 1
else:
raise 'Illegal option %s\n%s' % (opt[0], usage)
# check that all required arguments passed in
if url == None:
print '--url argument required - must be the url of the main page of a Madrigal site'
sys.exit(0)
if parms == None:
print '--parms argument required - must be a comma-separated list of Madrigal mnemonics'
sys.exit(0)
if output == None:
print '--output argument required - must be a valid, writable file path'
sys.exit(0)
# set startDate
if startDate == None:
startyear = 1950
startmonth = 1
startday = 1
else:
dateList = string.split(startDate, '/')
if len(dateList) != 3:
print '--startDate must be in the form MM/DD/YYYY: ' + str(startDate)
sys.exit(0)
startmonth = int(dateList[0])
startday = int(dateList[1])
startyear = int(dateList[2])
if startmonth < 1 or startmonth > 12 or startday < 1 or startday > 31:
print '--startDate must be in the form MM/DD/YYYY: ' + str(startDate)
sys.exit(0)
# set endDate
if endDate == None:
# chose one year from today
nextYear = time.time() + 365*24*60*60
nextYear = time.gmtime(nextYear)
endyear = nextYear[0]
endmonth = nextYear[1]
endday = nextYear[2]
else:
dateList = string.split(endDate, '/')
if len(dateList) != 3:
print '--endDate must be in the form MM/DD/YYYY: ' + str(endDate)
sys.exit(0)
endmonth = int(dateList[0])
endday = int(dateList[1])
endyear = int(dateList[2])
if endmonth < 1 or endmonth > 12 or endday < 1 or endday > 31:
print '--endDate must be in the form MM/DD/YYYY: ' + str(endDate)
sys.exit(0)
# verify the url is valid
server = madrigalWeb.MadrigalData(url)
# now, create a list of instrument codes desired from the inst argument
instList = getInstrumentList(inst, server)
# get the list of all experiments for the given instruments and time range
expList = server.getExperiments(instList,
startyear,
startmonth,
startday,
0,
0,
0,
endyear,
endmonth,
endday,
23,
59,
59)
# filter experiments using seasonal filter if needed
if seasonalStartDate != '01/01' or seasonalEndDate != '12/31':
expList = filterExperimentsUsingSeason(expList, seasonalStartDate, seasonalEndDate)
# get list of all experiment files given the expList
expFileList = getExperimentFileList(server, expList)
# filter expFileList using kindat filter if needed
if kindat != '0':
expFileList = filterExperimentFilesUsingKindat(expFileList, kindat)
# print error if no files selected
if len(expFileList) == 0:
print 'No files selected with these arguments'
sys.exit(0)
# open output file
outputFile = open(output, 'w')
# print summary if desired:
if showSummary:
summary = 'global isprint run %s with the following arguments:\n' % (time.asctime())
for arg in sys.argv[1:]:
summary += '%s\n' % (str(arg))
outputFile.write(summary)
# print header in all cases
header = string.join(string.split(parms,','), ' ')
outputFile.write(header + '\n')
# print message if verbose
numFiles = len(expFileList)
if verbose:
print "%i files being analyzed" % (numFiles)
# isprint to output file from each expFileList
filterStr = string.join(filterList, ' ')
for i in range(numFiles):
if verbose:
print 'Analyzing file %i of %i: %s' % (i+1, numFiles, expFileList[i].name)
if showFiles:
outputFile.write('%s\n' % (expFileList[i].name))
data = server.isprint(expFileList[i].name,
parms,
filterStr)
# modify any special value
if missing != 'missing':
data = string.replace(data, 'missing', missing)
if assumed != 'assumed':
data = string.replace(data, 'assumed', assumed)
if missing != 'knownbad':
data = string.replace(data, 'knownbad', knownbad)
outputFile.write(data[1:]) # skip leading space
outputFile.close()