Minor enhancements

This commit is contained in:
Zimmerberger Markus
2023-07-05 09:17:03 +02:00
parent 55b4fc9fd8
commit cb6e6074fb
6 changed files with 703 additions and 51 deletions
+414
View File
@@ -0,0 +1,414 @@
#!/usr/bin/env python
# coding=utf-8
# Created by: Brent Goodman
# Date: April 07, 2018
# Comments: Uses the Python Requests library to do REST API calls to v9 ARSystem Enviornments
# Alot of the information is hard-coded, but easy to see how to accomodate other values
# etc. All the functions have been tested and work in my new enviornment. All the code
# makes use of the "AP-Sample:Restaurant" form for testing. The 'params=' has some
# catches that need to be watched out for. I have documented comments through out.
# Very limited error checking has been implemented in this version of the code.
# Note that C# is my goto language. I only use python for development work on
# micro-controllers, so the code I provide may not be the most clean/effecive way
# of doing things, but it does get the results needed.
import json
import requests
import datetime
import time
requests.packages.urllib3.disable_warnings()
# Method: GET, POST, PUT, DELET
# URL: http://<>/api
# Authentication: Basic HTTP, OAuth, none
# Custom Headers: Content-Type: application/json
# Request Body:
# Response Status Codes: 200 OK, 201 Created, 500 Internal Error
# Way to find fields that can contain data
# select * from field where schemaid = (select schemaid from arschema where name ='Your Form Name') and foption <=3 order by fieldid;
# Setup the server name to be used by all the URL's
bg_ServerName = "smartitm01-prod.wienkav.at/smartit/app"
bg_UserID = "zim9003"
bg_Password = "3S1punk08_111$"
def doLogin():
myToken = ""
bgReturnVal = -1
url = 'https://' + bg_ServerName + '/api/jwt/login'
payload = {'username': bg_UserID, 'password': bg_Password}
headers = {'content-type': 'application/x-www-form-urlencoded'}
r = requests.post(url, data=payload, headers=headers, verify=False)
if r.status_code == 200:
myToken = r.text
bgReturnVal = 1
else:
print("Failure...")
print("Status Code: " + str(r.status_code))
bgReturnVal = -1
myToken = r.text
return(bgReturnVal, myToken)
def doLogout(bg_Token):
bgTokenType = 'AR-JWT'
myURL = 'https://' + bg_ServerName + '/api/jwt/logout'
myHeaders = {'Authorization': bgTokenType + ' ' + bg_Token}
myR = requests.post(myURL, headers=myHeaders, verify=False)
print("")
print("Logged out with a status of: {}".format(myR.status_code))
# Pull all data back from form
def doPullData(bg_FormName, bg_Token):
bgTokenType = 'AR-JWT'
myURL = 'https://' + bg_ServerName + '/api/arsys/v1/entry/' + bg_FormName
myHeaders = {'Authorization': bgTokenType + ' ' + bg_Token}
# Pull back all data in the form
myR = requests.get(url = myURL, headers = myHeaders, verify=False)
print("URL Used:")
print(myR.url)
print("")
if(myR.status_code != 200):
print('Status code:', myR.status_code)
print('Headers:', myR.headers)
print('Error Response:', myR.json())
return(-1)
bgData = myR.json()
# bgData contains a dictionay of two items:
# entries
# _links
# Copy the dictionary 'entries' into variable
avar = bgData['entries']
# len(avar) will tell us the number of returned records
# Loop the number of records returned
for x in range(len(avar)):
# Grab the dictionary of 'values'
myVals = avar[x]['values']
# Print out the key/value pair
for keys,values in myVals.items():
print('{} => {}'.format(keys,values))
print("")
return(len(avar))
# Pull all records back from form, but limited field list
def doPullData_LimitedFields(bg_FormName, bg_Token):
bgTokenType = 'AR-JWT'
myURL = 'https://' + bg_ServerName + '/api/arsys/v1/entry/' + bg_FormName
myHeaders = {'Authorization': bgTokenType + ' ' + bg_Token}
# Setup the list of fields only to return
# *** BMC REST API unable to handle this and I consider it a defect on their side
# Their documentation is incorrect
#fieldList_params = {'fields': "values(Restaurant,Status)"}
# Note that BMC documentation is wrong on this. The REST API on their
# end is not able to decode the FIELDS, LIMIT, or SORT.
# These must be appeneded to the URL. Only the Query can be urlencoded
# and put into the 'params=' variable
# *** Looks like everything inside of the ( ) needs to be encoded if any non
# URL safe characters are used. Still not able to push this into the 'params='
# variable as the "values()" also gets encoded. The brackes must not be encoded
# Javascript/Java may handle the pramameters a little differently.
bgFields = "Restaurant,Status"
bgTmp = myURL + "?fields=values(" + bgFields + ")"
# Setup the qualfication. This automatically gets encoded via the 'params=' variable
bgQuery = "'Restaurant' LIKE \"Test%\" AND 'Status' = \"Proposed\""
# Setup the search parameter to pass
search_params = {'q': bgQuery}
# Pull back all data in the form (The 'params=' will automcatially encode its contents)
#myR = requests.get(url = myURL, headers = myHeaders, params=fieldList_params, verify=False)
#myR = requests.get(url = myURL, headers = myHeaders, verify=False)
# Using a modified version of the URL + Fields restriction
myR = requests.get(url = bgTmp, headers = myHeaders, params=search_params, verify=False)
print("URL Used:")
print(myR.url)
print("")
if(myR.status_code != 200):
print('Status code:', myR.status_code)
print('Headers:', myR.headers)
print('Error Response:', myR.json())
return(-1)
bgData = myR.json()
#print(bgData)
# bgData contains a dictionay of two items:
# entries
# _links
# Copy the dictionary 'entries' into variable
avar = bgData['entries']
# len(avar) will tell us the number of returned records
# Loop the number of records returned
for x in range(len(avar)):
# Grab the dictionary of 'values'
myVals = avar[x]['values']
# Print out the key/value pair
for keys,values in myVals.items():
print('{} => {}'.format(keys,values))
print("")
return(len(avar))
def doPullSearchData(bg_FormName, bg_Token):
bgTokenType = 'AR-JWT'
myHeaders = {'Authorization': bgTokenType + ' ' + bg_Token}
myURL = 'https://' + bg_ServerName + '/api/arsys/v1/entry/' + bg_FormName
# Enter in your search criteria as you would in the Mid-tier advanced search
# Dont forget to escape out your quotes...
#bgQuery = "'Restaurant' = \"Test Snack Hut\""
#bgQuery = "'Restaurant' LIKE \"Test%\""
bgQuery = "'Restaurant' LIKE \"Test%\" AND 'Status' = \"Proposed\""
# Setup the search parameter to pass
search_params = {'q': bgQuery}
myR = requests.get(url=myURL, headers=myHeaders, verify=False, params=search_params)
print("URL Used:")
print(myR.url)
print("")
if(myR.status_code != 200):
print('Status code:', myR.status_code)
print('Headers:', myR.headers)
print('Error Response:', myR.json())
return(-1)
bgData = myR.json()
# Copy the dictionary 'entries' into variable
avar = bgData['entries']
# len(avar) will tell us the number of returned records
# Loop the number of records returned
for x in range(len(avar)):
# Grab the dictionary of 'values'
myVals = avar[x]['values']
# Print out the key/value pair
for keys,values in myVals.items():
print('{} => {}'.format(keys,values))
print("")
return(len(avar))
# Pull all data back from form
def doPullSingleRequestIDData(bg_FormName, bg_RequestID, bg_Token):
bgTokenType = 'AR-JWT'
myURL = 'https://' + bg_ServerName + '/api/arsys/v1/entry/' + bg_FormName + '/' + bg_RequestID
myHeaders = {'Authorization': bgTokenType + ' ' + bg_Token}
# Pull back all data in the form
myR = requests.get(url = myURL, headers = myHeaders, verify=False)
print("URL Used:")
print(myR.url)
print("")
if(myR.status_code != 200):
print('Status code:', myR.status_code)
print('Headers:', myR.headers)
print('Error Response:', myR.json())
return(-1)
bgData = myR.json()
# bgData contains a dictionay of two items:
# entries
# _links
#print(bgData)
# Copy the dictionary 'entries' into variable
avar = bgData['values']
# Print out the key/value pair
for keys,values in avar.items():
print('{} => {}'.format(keys,values))
return(len(avar))
# Create a record in form
def doCreateRecord(bg_FormName, bg_Token):
bgTokenType = 'AR-JWT'
myURL = 'https://' + bg_ServerName + '/api/arsys/v1/entry/' + bg_FormName
myHeaders = {'Authorization': bgTokenType + ' ' + bg_Token, 'Content-Type': 'application/json'}
# Setting the data= like this will not work. Must be in the raw JSON format
#payload = {'Restaurant':'Test Cheese House','Status':'Active','Average Cost/Person':12.99,'Assigned To':'Bob'}
# Format of the data= information must use the following template:
# {
# "values":{
# "Restaurant":"Test MacEnCheese", <-- Start of the fields list to set
# "Status":"Active",
# "Average Cost/Person":2.99,
# "Assigned To":"Bob" <-- End of the fields list to set
# }
# }
payload = '{ \"values\":{\"Restaurant\":\"Test Pizza World\",\"Status\":\"Active\",\"Average Cost/Person\":2.99,\"Assigned To\":\"Bob\"} }'
# Pull back all data in the form
myR = requests.post(url = myURL, data=payload, headers = myHeaders, verify=False)
if(myR.status_code != 201):
print('Status code:', myR.status_code)
print('Headers:', myR.headers)
print('Error Response:', myR.json())
return(-1)
print("URL to new record:")
print(myR.headers['location'])
print("")
return(1)
# Modify an Entry
def doModifySingleRequestIDData(bg_FormName, bg_RequestID, bg_Token):
bgTokenType = 'AR-JWT'
myURL = 'https://' + bg_ServerName + '/api/arsys/v1/entry/' + bg_FormName + '/' + bg_RequestID
myHeaders = {'Authorization': bgTokenType + ' ' + bg_Token, 'Content-Type':'application/json'}
payload = '{ \"values\":{\"Status\":\"Inactive\",\"Average Cost/Person\":3.99,\"Assigned To\":\"Rick\"} }'
# Pull back all data in the form
myR = requests.put(url = myURL, headers = myHeaders, data=payload, verify=False)
print("URL Used:")
print(myR.url)
print("")
print("Status of Update: {}".format(myR.status_code))
# 204 = sucessful updateTime
# 412 = unmodified (same data was pushed)
if(myR.status_code != 204):
if(myR.status_code != 412):
# 403 = Forbidden
# 404 = Form does not exist
print('Status code:', myR.status_code)
print("")
print('Headers:', myR.headers)
print("")
print('Error Response:', myR.json())
return(-1)
def getFormDefinition(bg_FormName, bg_Token):
bgTokenType = 'AR-JWT'
myURL = 'https://' + bg_ServerName + '/api/arsys/v1/entry/' + bg_FormName
myHeaders = {'Authorization': bgTokenType + ' ' + bg_Token}
myR = requests.options(url = myURL, headers = myHeaders, verify=False)
print("URL Used:")
print(myR.url)
print("")
print("Status of call: {}".format(myR.status_code))
bgData = myR.json()
# Print the raw data returned
#print(bgData)
# Drill down and only pull out the field information
avar = bgData['properties']['values']['properties']
# Print the new raw data
#print(avar)
print("")
print("-----Key Value pairs-----")
print("")
# Loop through all the fields returned
for key in sorted(avar.keys()):
print("Key: {}".format(key))
# Pull out a field to look at
tmp = avar[key]
# Print out the 'type' keys data. Exists for all fields
print("Type: {}".format(tmp['type']))
# If the key exists, print it out
if 'maxLength' in tmp:
print("Length: {}".format(tmp['maxLength']))
if 'format' in tmp:
print("Format: {}".format(tmp['format']))
if 'required' in tmp:
print("Required: {}".format(tmp['required']))
print("")
print("")
print("-----------------------")
print("")
def main():
# Login and get token
bgReturnVal, bgToken = doLogin()
# Only continue if we logged in successfully
if bgReturnVal == 1:
# Pull all records
#bgResult = doPullData("AP-Sample:Restaurant", bgToken)
#if(bgResult == -1):
# print("An error occured...")
#else:
# print("Found {} record(s) in our last query".format(bgResult))
# Pull all records back, but only certain fields
#bgResult = doPullData_LimitedFields("AP-Sample:Restaurant", bgToken)
# Pull records based on hard coded query
#bgResult = doPullSearchData("AP-Sample:Restaurant", bgToken)
# Pull record back based on its RequestID. This is a standard format
#doPullSingleRequestIDData("AP-Sample:Restaurant", "000000000000105", bgToken)
# Create a new recodrs in the form (hard coded values used)
#bgResult = doCreateRecord("AP-Sample:Restaurant", bgToken)
# Modify the record based on its RequestID. This is a standard format
#doModifySingleRequestIDData("AP-Sample:Restaurant", "000000000000105", bgToken)
# Get definitions of all the fields on form
getFormDefinition("AP-Sample:Restaurant", bgToken)
# Logout
doLogout(bgToken)
main()