Browse Source

add get properties function

master
Gerry Nelson 5 years ago
parent
commit
ee1ef34351
  1. 403
      sharedfunctions.py

403
sharedfunctions.py

@ -14,16 +14,16 @@
#
# Change History
#
# 27JAN2018 Comments added
# 29JAN2018 Added simpleresults function
# 31JAN2018 Added the ability to pass contenttype to call_rest_api (now callrestapi)
# 27JAN2018 Comments added
# 29JAN2018 Added simpleresults function
# 31JAN2018 Added the ability to pass contenttype to call_rest_api (now callrestapi)
# 31JAN2018 Improved error handling of call_rest_api (now callrestapi)
# 31JAN2018 Deal with situation where json is not returned
# 31JAN2018 Deal with situation where json is not returned
# 31JAN2018 Fix a bug when neither json or text is returned
# 02FEB2018 Fix a bug when text is returned
# 12MAR2018 Made simple result print generic
# 20MAR2018 Added some comments
# 20MAR2018 Handle errors when profile and authentication token do not exist
# 02FEB2018 Fix a bug when text is returned
# 12MAR2018 Made simple result print generic
# 20MAR2018 Added some comments
# 20MAR2018 Handle errors when profile and authentication token do not exist
# 20May2018 Fixed bug in authentication check
# 01jun2018 Deal with empty profile error
# 23oct2018 Added print result function
@ -62,23 +62,23 @@ pp = pprint.PrettyPrinter(indent=4)
# validate rest api is not used at this time
# not used
def validaterestapi(baseurl, reqval, reqtype, data={}):
global result
print("The request is a "+reqtype+" request: ",baseurl+reqval)
json_data=json.dumps(data, ensure_ascii=False)
print("Data for Request:")
print(json_data)
if (reqtype !="get" or reqtype !="post" or reqtype!="delete" or reqtype!="put"):
if (reqtype !="get" or reqtype !="post" or reqtype!="delete" or reqtype!="put"):
print("NOTE: Invalid method")
return;
# callrestapi
# this is the main function called many other programs and by the callrestapi program to make the REST calls
# change history
@ -86,26 +86,26 @@ def validaterestapi(baseurl, reqval, reqtype, data={}):
# 28oct2018 Added stop on error to be able to override stopping processing when an error occurs
def callrestapi(reqval, reqtype, acceptType='application/json', contentType='application/json',data={},stoponerror=1):
# get the url from the default profile
baseurl=getbaseurl()
# get the auth token
oaval=getauthtoken(baseurl)
# build the authorization header
head= {'Content-type':contentType,'Accept':acceptType}
head.update({"Authorization" : oaval})
# maybe this can be removed
# maybe this can be removed
global result
# sereliaze the data string for the request to json format
json_data=json.dumps(data, ensure_ascii=False)
# call the rest api using the parameters passed in and the requests python library
# call the rest api using the parameters passed in and the requests python library
if reqtype=="get":
ret = requests.get(baseurl+reqval,headers=head,data=json_data)
elif reqtype=="post":
@ -117,20 +117,20 @@ def callrestapi(reqval, reqtype, acceptType='application/json', contentType='app
else:
result=None
print("NOTE: Invalid method")
sys.exit()
# response error if status code between these numbers
sys.exit()
# response error if status code between these numbers
if (400 <= ret.status_code <=599):
print(ret.text)
result=None
if stoponerror: sys.exit()
# return the result
print(ret.text)
result=None
if stoponerror: sys.exit()
# return the result
else:
# is it json
try:
# is it json
try:
result=ret.json()
except:
# is it text
@ -139,11 +139,11 @@ def callrestapi(reqval, reqtype, acceptType='application/json', contentType='app
except:
result=None
print("NOTE: No result to print")
return result;
# getfolderid
# when a Viya content path is passed in return the id, path and uri
# change history
@ -151,11 +151,11 @@ def callrestapi(reqval, reqtype, acceptType='application/json', contentType='app
# 08Feb2020 return full json as 4 item in list that is returned
def getfolderid(path):
# build the request parameters
# build the request parameters
reqval="/folders/folders/@item?path="+path
reqtype='get'
callrestapi(reqval,reqtype)
if result==None:
@ -167,10 +167,10 @@ def getfolderid(path):
targetid=result['id']
targetname=result['name']
targeturi="/folders/folders/"+targetid
return [targetid,targeturi,targetname,result]
# getbaseurl
# from the default profile return the baseurl of the Viya server
# change history
@ -178,7 +178,7 @@ def getfolderid(path):
# 01jun2018 Deal with empty profile error
# 20nov2018 Use the SAS_CLI_PROFILE env variable
def getbaseurl():
# check that profile file is available and can be read
@ -200,13 +200,13 @@ def getbaseurl():
# get json from profile
with open(endpointfile) as json_file:
data = json.load(json_file)
# get the profile environment variable to use it
# if it is not set default to the default profile
cur_profile=os.environ.get("SAS_CLI_PROFILE","Default")
#print("URL: ",cur_profile )
# check that information is in profile
if cur_profile in data:
baseurl=data[cur_profile]['sas-endpoint']
@ -221,57 +221,57 @@ def getbaseurl():
# getauthtoken
# from the stored auth file get the authentication token for the request header
# from the stored auth file get the authentication token for the request header
# change history
# 01dec2017 initial development
# return oaval=None when no authtoken retrieved
# 20nov2018 Use the SAS_CLI_PROFILE env variable
def getauthtoken(baseurl):
#get authentication information for the header
credential_file=os.path.join(os.path.expanduser('~'),'.sas','credentials.json')
# check that credential file is available and can be read
access_file=file_accessible(credential_file,'r')
if access_file==False:
oaval=None
print("ERROR: Cannot read authentication credentials at: ", credential_file)
print("ERROR: Try refreshing your token with sas-admin auth login")
sys.exit()
with open(credential_file) as json_file:
with open(credential_file) as json_file:
data = json.load(json_file)
type(data)
# the sas-admin profile init creates an empty credential file
# check that credential is in file, if it is add it to the header, if not exit
# get the profile environment variable to use it
# if it is not set default to the default profile
cur_profile=os.environ.get("SAS_CLI_PROFILE","Default")
#print("LOGON: ", cur_profile )
if cur_profile in data:
oauthToken=data[cur_profile]['access-token']
oauthTokenType="bearer"
oaval=oauthTokenType + ' ' + oauthToken
head= {'Content-type':'application/json','Accept':'application/json' }
head.update({"Authorization" : oaval})
# test a connection to rest api if it fails exit
r = requests.get(baseurl,headers=head)
if (400 <= r.status_code <=599):
oaval=None
print(r.text)
print("ERROR: cannot connect to "+baseurl+" is your token expired?")
@ -283,69 +283,69 @@ def getauthtoken(baseurl):
print("ERROR: access token not in file: ", credential_file)
print("ERROR: Try refreshing your token with sas-admin auth login")
sys.exit()
return oaval
# getinputjson
# load the returned json to a python dictionary
# change history
# 01dec2017 initial development
def getinputjson(input_file):
with open(input_file) as json_file:
inputdata = json.load(json_file)
return inputdata
return inputdata
# simpleresults
# take the complex json and create a simple print of the results
# change history
# 01dec2017 initial development
# 20dec2018 simple output now alphibetical order by key
def simpleresults(resultdata):
# print a simplification of the json results
# list of items returned by rest call
if 'items' in resultdata:
total_items=resultdata['count']
returned_items=len(resultdata['items'])
if total_items == 0: print("Note: No items returned.")
for i in range(0,returned_items):
for i in range(0,returned_items):
print ("=====Item ",i,"=======")
origpairs=resultdata['items'][i]
test=origpairs.get('description')
test=origpairs.get('description')
if test==None: origpairs['description']='None'
pairs=collections.OrderedDict(sorted(origpairs.items()))
for key,val in pairs.items():
if key != 'links':
if key != 'links':
print(key,end="")
print(" = ", val)
print("Result Summary: Total items available: ",total_items ,"Total items returned: ", returned_items)
elif 'id' in resultdata: #one item returned by rest call
for key,val in resultdata.items():
if key != 'links':
if key != 'links':
print(key,end="")
print(" = ", val)
else:
print("NOTE: No JSON Results Found")
@ -355,123 +355,123 @@ def simpleresults(resultdata):
# take the complex json and create a simple table of the results
# change history
# 01aug2018 initial development
# 19dece2018 print csv in column orderwith only common columns
# 19dece2018 print csv in column orderwith only common columns
def csvresults(resultdata,columns=[]):
if 'items' in resultdata:
total_items=resultdata['count']
returned_items=len(resultdata['items'])
if total_items == 0: print("Note: No items returned.")
for i in range(0,returned_items):
for i in range(0,returned_items):
origpairs=resultdata['items'][i]
# create an ordered dictionary
pairs=collections.OrderedDict()
# loop thru the column list and insert to a new dictionary in that order
# this ensures that colums appear in this order in the csv
for keylabel in columns:
# get the value for the current column
curval=origpairs.get(keylabel)
if curval != None:
pairs[keylabel] = curval
else:
pairs[keylabel] = 'None'
pairs[keylabel] = 'None'
numvals=len(columns)
z=0
# print header row of column names
for key,val in pairs.items():
z=z+1
z=z+1
# seperate with comma except last item
if z==numvals: sep=''
else: sep=','
if i==0 and key in columns: print(key,sep,end="")
print("\n",end="")
z=0
# print rows
for key,val in pairs.items():
# seperate with comma except last item
z=z+1
if z==numvals: sep=''
else: sep=','
if key != 'links' and key in columns: print('"'+str(val)+'"'+sep, end="")
print("\n",end="")
elif 'id' in resultdata: #one item returned by rest call
numvals=len(resultdata.items())
z=0
for key,val in resultdata.items():
# seperate with comma except last item
z=z+1
if z==numvals: sep=''
else: sep=','
if key != 'links': print(key,sep,end="")
print("\n",end="")
z=0
for key,val in resultdata.items():
# seperate with comma except last item
z=z+1
if z==numvals: sep=''
else: sep=','
if key != 'links': print('"'+str(val)+'"'+sep,end="")
print("\n",end="")
else:
print("NOTE: No JSON Results Found")
# file_accessible
# Check if a file exists and is accessible.
# Check if a file exists and is accessible.
# change history
# 01dec2017 initial development
def file_accessible(filepath, mode):
try:
f = open(filepath, mode)
f.close()
except IOError as e:
return False
return True
# printresult
# prints the results in the style requested
# prints the results in the style requested
# change history
# 28oct2018 initial development
# 22dec2018 add csv columns only relevent for csv output, defaults provided but can be overriden when called
@ -479,10 +479,10 @@ def file_accessible(filepath, mode):
def printresult(result,output_style,colsforcsv=["id","name","type","description","creationTimeStamp","modifiedTimeStamp"]):
# print rest call results
if type(result) is dict:
if output_style=='simple':
simpleresults(result)
elif output_style=='simplejson':
@ -491,54 +491,54 @@ def printresult(result,output_style,colsforcsv=["id","name","type","description"
csvresults(result,columns=colsforcsv)
else:
print(json.dumps(result,indent=2))
else: print(result)
else: print(result)
# getprofileinfo
# prints the token expiration, endpoint and current user
# change history
# 20nov2018 initial development
def getprofileinfo(myprofile):
#get authentication information for the header
credential_file=os.path.join(os.path.expanduser('~'),'.sas','credentials.json')
# check that credential file is available and can be read
access_file=file_accessible(credential_file,'r')
if access_file==False:
print("ERROR: Cannot read authentication credentials at: ", credential_file)
print("ERROR: Try refreshing your token with sas-admin auth login")
sys.exit()
with open(credential_file) as json_file:
with open(credential_file) as json_file:
data = json.load(json_file)
type(data)
# the sas-admin profile init creates an empty credential file
# check that credential is in file, if it is add it to the header, if not exit
# get the profile environment variable to use it
# if it is not set default to the default profile
if myprofile in data:
expiry=data[myprofile]['expiry']
print("Note your authentication token expires at: "+expiry)
else:
print("ERROR: access token not in file: ", credential_file)
print("ERROR: Try refreshing your token with sas-admin auth login")
sys.exit()
# note the path to the profile is hard-coded right now
endpointfile=os.path.join(os.path.expanduser('~'),'.sas','config.json')
access_file=file_accessible(endpointfile,'r')
@ -556,30 +556,30 @@ def getprofileinfo(myprofile):
# get json from profile
with open(endpointfile) as json_file:
data = json.load(json_file)
# check that information is in profile
if myprofile in data:
baseurl=data[myprofile]['sas-endpoint']
print("Endpoint is: "+baseurl)
else:
print("ERROR: profile "+myprofile+" does not exist. Recreate profile with sas-admin profile init.")
# build the request parameters
# build the request parameters
reqval="/identities/users/@currentUser"
reqtype='get'
result=callrestapi(reqval,reqtype)
if result==None:
print("NOTE: Not logged in.")
else:
print("Logged on as id: "+ result['id'])
print("Logged on as name: "+result['name'])
# getpath
# when a Viya objectURI is passed in return the path
# change history
@ -611,7 +611,7 @@ def getpath(objecturi):
return path
# getidsanduris
# given a result json structure, return a dictionary with a list of id's and uri's
# given a result json structure, return a dictionary with a list of id's and uri's
# change history
# 01dec2017 initial development
@ -620,50 +620,65 @@ def getidsanduris(resultdata):
resultdict={}
resultdict['ids']=[]
resultdict['uris']=[]
# loop the result and add a list of ids and uris to the returned dictionary
if 'items' in resultdata:
total_items=resultdata['count']
returned_items=len(resultdata['items'])
if total_items == 0: print("Note: No items returned.")
for i in range(0,returned_items):
for i in range(0,returned_items):
resultdict['ids'].append(resultdata['items'][i]['id'])
resultdict['uris'].append(resultdata['items'][i]['uri'])
return resultdict
# simplejsonresults
# given a result json structure, remove all the "links" items
# this will return a more readable json output
# this will return a more readable json output
# change history
# 20feb2020 initial development
def simplejsonresults(resultdata):
if 'items' in resultdata: # list of items returned by rest call
for key in list(resultdata):
if key == 'links': del resultdata[key]
for key in list(resultdata):
if key == 'links': del resultdata[key]
total_items=resultdata['count']
returned_items=len(resultdata['items'])
if total_items == 0: print("Note: No items returned.")
for i in range(0,returned_items):
for i in range(0,returned_items):
for key in list(resultdata['items'][i]):
if key=='links':
if key=='links':
del resultdata['items'][i][key]
print(json.dumps(resultdata,indent=2))
elif 'id' in resultdata: #one item returned by rest call
del resultdata['links']
del resultdata['links']
print(json.dumps(resultdata,indent=2))
def getapplicationproperties:
# get the path for the script file this is where the properties file will bbe
thepath=os.path.split(inspect.getsourcefile(lambda:0))
install_dir=thepath[0]
prop_file=os.path.join(install_dir, "application.properties")
myparams=dict(line.strip().split('=') for line in open(prop_file) if line[0].isalpha())
print(myparams)
return myparms

Loading…
Cancel
Save