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
+3 -1
View File
@@ -9,7 +9,9 @@
"type": "python", "type": "python",
"request": "launch", "request": "launch",
"program": "${file}", "program": "${file}",
"console": "integratedTerminal" "console": "integratedTerminal",
"justMyCode": false,
"pythonArgs": ["-Xfrozen_modules=off"]
} }
] ]
} }
+28
View File
@@ -0,0 +1,28 @@
from jira import JIRA, Issue, exceptions
import logging
def get_assignee(type, issue):
isBuergerfrontend = False
if type == 'Dev Backend':
return 'reu9001'
elif type == 'Dev Frontend':
for component in issue.fields.components:
isBuergerfrontend = component.name == "Bürgerfrontend"
if isBuergerfrontend:
return 'reu9001'
return 'thh9001'
elif type.startswith('Test-Anpassung'):
return 'ada9001'
def create_subtask(issue, parent, type, subtask_sp, estimation_remark):
escaped = issue.fields.summary.replace('"', r'\"')
logging.info(f'summary ~ \"{escaped}\"')
try:
subtask = jira_server.search_issues(f'summary ~ \"{type} {escaped}\"')
if subtask:
raise exceptions.JIRAError
except exceptions.JIRAError:
logging.info(f'Skip creating Sub-Task {type} for {issue} as it already exists')
return
+189
View File
@@ -0,0 +1,189 @@
# find comments with estimations out of pre-planning
# zisco 2021-09-30 19:50
from types import ClassMethodDescriptorType
from jira import JIRA, Issue, Comment, exceptions
from atlassian import Confluence
from bs4 import BeautifulSoup
import re
import csv
import xlsxwriter
import logging
import requests
import pandas as pd
def get_priority(priority):
match priority:
case "GreenMVP":
return "Highest"
case _:
return "Medium"
def get_assignee():
return 'raj9002'
isBuergerfrontend = False
if type == 'Dev Backend':
#return 'rab9001'
return 'reu9001'
elif type == 'Dev Frontend':
# consider verwaltungsfrontend or bürgerfrontend
existingComponents = []
for component in issue.fields.components:
if component.name == "Bürgerfrontend":
isBuergerfrontend = True
if isBuergerfrontend:
return 'reu9001'
else:
return 'thh9001'
elif type[:14] == 'Test-Anpassung':
return 'ada9001'
def create_epic(use_case, priority):
escaped = use_case.replace('"','\\"')
epic = jira_server.search_issues('project = 19404 AND summary ~ \"{}\"'.format(escaped))
if len(epic) == 0:
issue_type = 'Epic'
assignee = get_assignee()
issue_dict = {
'project': {'id': 19404},
'summary': escaped,
'description': escaped,
'issuetype': {'name': issue_type},
'priority': {'name': get_priority(priority)},
'customfield_10019': escaped,
#'parent': {'key': parent},
#'labels': issue.fields.labels,
#'customfield_10022' - Story Points
#'timetracking': {'originalEstimate': "{}d".format(subtask_sp)},
'assignee': {'name': assignee}
}
try:
new_issue = jira_server.create_issue(fields=issue_dict)
except:
print("Something")
# consider components
#existingComponents = []
#for component in issue.fields.components:
# existingComponents.append({"name" : component.name})
#new_issue.update(fields={"components": existingComponents})
#new_issue.update(priority={"name": issue.fields.priority.name})
logging.info('Created Epic {}'.format(new_issue))
else:
#update
epic = jira_server.issue(epic[0])
logging.info('Skip creating Epic {} as it already exists'.format(epic.key))
logging.basicConfig(filename='epic_generator.log',
filemode='a',
format='%(asctime)s - %(levelname)s: %(message)s',
level=logging.INFO,
encoding='utf-8')
jira_host = "https://jira.wien.gv.at/"
confluence_host = "https://confluence.wien.gv.at/"
jira_pat = "OTAyMTM3MjY0MjE0Ovz6bu0ti1TlEdSegmmiWiJ2wGeD"
confluence_pat = "MDI3ODU2NzkzMTAyOsPz47kjJvVdJa1bLpen3W5sB6S5"
sprint = 57
headers = JIRA.DEFAULT_OPTIONS["headers"].copy()
headers["Authorization"] = f"Bearer {jira_pat}"
jira_server = JIRA(server=jira_host, options={"headers": headers})
s = requests.Session()
s.headers['Authorization'] = f"Bearer {confluence_pat}"
confluence = Confluence(url=confluence_host, session=s)
page_id = 215812836
page = confluence.get_page_by_id(page_id, expand="body.storage", status=None, version=None)
body = page["body"]["storage"]["value"]
tables_raw = [[[cell.text for cell in row("th") + row("td")]
for row in table("tr")]
for table in BeautifulSoup(body, features="lxml")("table")]
logging.info('Creating epics out of confluence description')
#xsp = lambda s: s or 0
tables_df = [pd.DataFrame(table) for table in tables_raw]
for table_df in tables_df:
for index in table_df.index:
if index >= 11 and index <= 12:
create_epic(use_case=table_df[1][index],
priority=table_df[2][index])
issue: Issue
for issue in issues_Jql:
logging.info('Working on {}'.format(issue))
sp_sum = 0
# only Issues with empty (or 0) story-points
sp = 0
if hasattr(issue.fields, 'customfield_10022'):
sp = xsp(issue.fields.customfield_10022)
if sp != 0:
logging.info('Ignoring issue {} as there are Story-Points already omitted'.format(issue))
else:
single_issue = jira_server.issue(issue.key)
comments = single_issue.fields.comment.comments
# Find all comments made by me on this issue.
for comment in comments:
comment_lines = comment.body.splitlines()
if len(comment_lines) == 5:
if comment_lines[0][:5] == "Dev B":
for comment_line in comment_lines:
if comment_line != "":
# pos = comment_lines[2].find('NN')
comment_line_parts = comment_line.split(':')
# if 1. Test* != NN create a sub-task (if not existing)
if len(comment_line_parts) == 2:
if comment_line_parts[1] != u'\xa0': # empty string
if (comment_line_parts[1][-2:] != 'NN') and (comment_line_parts[1][-1:] != '-'): # NN means NotNecessary
subtask_ph = float(comment_line_parts[1]) * 0.5
if comment_line_parts[0][:15] != "Test-Ausführung":
create_subtask(issue,
issue.key,
comment_line_parts[0],
subtask_ph)
sp_sum += subtask_ph / 0.5
# find corresponding sub-task
# issuelinks.inwardIssue
try:
if sp != sp_sum:
issue.update(fields={'customfield_10022': sp_sum})
logging.info("Estimated story-points changed to Sum(Sub-Tasks story-points): {}".format(sp_sum, sp_sum))
except exceptions.JIRAError:
logging.error("Issue {} has no (visible) Story Points-attribute".format(issue.key))
finally:
logging.info('Done {}'.format(issue.key))
#print('{}: {}, SP: {}'.format(issue.key, issue.fields.summary, sp))
#print('Summe {}: {}'.format(assignee, sp_sum))
#print(issues_Jql)
# changelog = issues_Jql.
# count = 0
# for history in changelog.histories:
# for item in history.items:
# if item.field == 'status':
# if item.toString == "Reopened":
# count = count + 1
# print(count)
+62 -48
View File
@@ -8,55 +8,60 @@ import csv
import xlsxwriter import xlsxwriter
import logging import logging
def get_assignee(type): def get_assignee(type, issue):
isBuergerfrontend = False
if type == 'Dev Backend': if type == 'Dev Backend':
#return 'rab9001'
return 'reu9001' return 'reu9001'
elif type == 'Dev Frontend': elif type == 'Dev Frontend':
# consider verwaltungsfrontend or bürgerfrontend for component in issue.fields.components:
isBuergerfrontend = component.name == "Bürgerfrontend"
if isBuergerfrontend:
return 'reu9001'
return 'thh9001' return 'thh9001'
# return 'reu9001' elif type.startswith('Test-Anpassung'):
elif type[:14] == 'Test-Anpassung':
return 'ada9001' return 'ada9001'
def create_subtask(issue, parent, type, subtask_sp): def create_subtask(issue, parent, type, subtask_sp, estimation_remark):
escaped = issue.fields.summary.replace('"','\\"') escaped = issue.fields.summary.replace('"', r'\"')
print('summary ~ \"{}\"'.format(escaped)) logging.info(f'summary ~ \"{escaped}\"')
subtask = jira_server.search_issues('summary ~ \"{} {}\"'.format(type, escaped)) try:
if len(subtask) == 0: subtask = jira_server.search_issues(f'summary ~ \"{type} {escaped}\"')
#right = (comment_line.find(':')+2)-len(comment_line) if subtask:
#subtask_sp = float(comment_line[right:]) raise exceptions.JIRAError
except exceptions.JIRAError:
logging.info(f'Skip creating Sub-Task {type} for {issue} as it already exists')
return
# issuetype of testcase-creation/modification should be 'Test' issue_type = 'Sub-task'
# if type == 'Test-Anpassung':
issue_type = 'Sub-task'
assignee = get_assignee(type) assignee = get_assignee(type, issue)
issue_dict = { description = 's. Story'
'project': {'id': 12501}, if estimation_remark != "":
'summary': "[{}] {}".format(type, escaped), description += "\nEstimation remark: {}".format(estimation_remark)
'description': issue.fields.description,
'issuetype': {'name': issue_type},
'priority': {'name': issue.fields.priority.name},
'parent': {'key': parent},
'labels': issue.fields.labels,
#'customfield_10022' - Story Points
'timetracking': {'originalEstimate': "{}d".format(subtask_sp)},
'assignee': {'name': assignee}
}
new_issue = jira_server.create_issue(fields=issue_dict)
# consider components issue_dict = {
existingComponents = [] 'project': {'id': issue.fields.project.id},
for component in issue.fields.components: 'summary': "[{}] {}".format(type, escaped),
existingComponents.append({"name" : component.name}) 'description': description, # issue.fields.description,
new_issue.update(fields={"components": existingComponents}) 'issuetype': {'name': issue_type},
#new_issue.update(priority={"name": issue.fields.priority.name}) 'priority': {'name': issue.fields.priority.name},
'parent': {'key': parent},
'labels': issue.fields.labels,
#'customfield_10022' - Story Points
'timetracking': {'originalEstimate': "{}d".format(subtask_sp)},
'assignee': {'name': assignee}
}
new_issue = jira_server.create_issue(fields=issue_dict)
logging.info('Created Sub-Task {}'.format(new_issue)) # consider components
else: existingComponents = []
logging.info('Skip creating Sub-Task {} for {} as it already exists'.format(type, issue)) for component in issue.fields.components:
existingComponents.append({"name" : component.name})
new_issue.update(fields={"components": existingComponents})
#new_issue.update(priority={"name": issue.fields.priority.name})
logging.info('Created Sub-Task {}'.format(new_issue))
logging.basicConfig(filename='sub_task_generator.log', logging.basicConfig(filename='sub_task_generator.log',
filemode='a', filemode='a',
@@ -66,15 +71,15 @@ logging.basicConfig(filename='sub_task_generator.log',
host = "https://jira.wien.gv.at/" host = "https://jira.wien.gv.at/"
pat = "OTAyMTM3MjY0MjE0Ovz6bu0ti1TlEdSegmmiWiJ2wGeD" pat = "OTAyMTM3MjY0MjE0Ovz6bu0ti1TlEdSegmmiWiJ2wGeD"
sprint = 46 sprint = 4
headers = JIRA.DEFAULT_OPTIONS["headers"].copy() headers = JIRA.DEFAULT_OPTIONS["headers"].copy()
headers["Authorization"] = f"Bearer {pat}" headers["Authorization"] = f"Bearer {pat}"
jira_server = JIRA(server=host, options={"headers": headers}) jira_server = JIRA(server=host, options={"headers": headers})
# use filter or single issue # use filter or single issue
issues_Jql = jira_server.search_issues('filter=20406') #, expand='changelog') issues_Jql = jira_server.search_issues('filter=22140') #, expand='changelog')
#issues_Jql = jira_server.search_issues('key in (WRGWR-1558)') #, expand='changelog') #issues_Jql = jira_server.search_issues('key in (DKARB-34)') #, expand='changelog')
#issues_Jql = jira_server.search_issues('labels in (Refinement11012022) AND type not in (Bug) AND status not in (Done) and ("Story Points" is EMPTY or "Story Points" = 0)') #, expand='changelog') #issues_Jql = jira_server.search_issues('labels in (Refinement11012022) AND type not in (Bug) AND status not in (Done) and ("Story Points" is EMPTY or "Story Points" = 0)') #, expand='changelog')
logging.info('Creating sub-tasks out of estimation of pre-planning sprint {}'.format(sprint)) logging.info('Creating sub-tasks out of estimation of pre-planning sprint {}'.format(sprint))
@@ -110,20 +115,29 @@ for issue in issues_Jql:
# if 1. Test* != NN create a sub-task (if not existing) # if 1. Test* != NN create a sub-task (if not existing)
if len(comment_line_parts) == 2: if len(comment_line_parts) == 2:
if comment_line_parts[1] != u'\xa0': # empty string if comment_line_parts[1] != u'\xa0': # empty string
if comment_line_parts[1][-2:] != 'NN': # NN means NotNecessary if (comment_line_parts[1][-2:] != 'NN') and (comment_line_parts[1][-1:] != '-'): # NN means NotNecessary
subtask_ph = float(comment_line_parts[1]) * 0.5 comment_line_sub_parts = comment_line_parts[1].split(' (')
if len(comment_line_sub_parts)>1:
subtask_ph = float(comment_line_sub_parts[0]) * 0.5
estimation_remark = comment_line_sub_parts[1]
else:
subtask_ph = float(comment_line_parts[1]) * 0.5
estimation_remark = ""
if comment_line_parts[0][:15] != "Test-Ausführung": if comment_line_parts[0][:15] != "Test-Ausführung":
create_subtask(issue, create_subtask(issue,
issue.key, issue.key,
comment_line_parts[0], comment_line_parts[0],
subtask_ph) subtask_ph,
estimation_remark)
sp_sum += subtask_ph / 0.5 sp_sum += subtask_ph / 0.5
# find corresponding sub-task # find corresponding sub-task
# issuelinks.inwardIssue # issuelinks.inwardIssue
try: try:
issue.update(fields={'customfield_10022': sp_sum}) if sp != sp_sum:
logging.info("Estimated story-points changed to Sum(Sub-Tasks story-points): {}".format(sp_sum, sp_sum)) issue.update(fields={'customfield_10022': sp_sum})
logging.info("Estimated story-points changed to Sum(Sub-Tasks story-points): {}".format(sp_sum, sp_sum))
except exceptions.JIRAError: except exceptions.JIRAError:
logging.error("Issue {} has no (visible) Story Points-attribute".format(issue.key)) logging.error("Issue {} has no (visible) Story Points-attribute".format(issue.key))
+5
View File
@@ -0,0 +1,5 @@
from remedy_py.RemedyAPIClient import RemedyClient
client = RemedyClient("smartitm01-prod.wienkav.at/", "zim9003", "3S1punk08_111$", port=None, verify=False)
print(client)
+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()