#!/usr/bin/env python3
import sys
import time
import requests
import xml.etree.ElementTree
API_HOST = 'api.evpsys.com'
API_VERSION = '1.3'
API_TOKEN = '{PUT-YOUR-TOKEN-HERE}'
API_KEY = '{PUT-YOUR-KEY-HERE}'
API_ACTOR_EMAIL = 'jane.doe@example.com'
API_ACTOR_WINDOWS_USER = None
LOCAL_PORTFOLIO_ID = 'joy-demo-portfolio-001'
LOT_IDS = {
1: 'joy-demo-lot-001',
2: 'joy-demo-lot-002',
3: 'joy-demo-lot-003',
4: 'joy-demo-lot-004',
}
INITIAL_REPORT_FILE_NAME = 'joy-demo-initial-report'
REVISED_REPORT_FILE_NAME = 'joy-demo-revised-report'
def get_document(text):
document = xml.etree.ElementTree.fromstring(text)
if document.find('status').text not in ['ok', 'pending']:
raise Exception(document.find('error-text').text)
return document
def get_url(path):
path = path if path.startswith('/') else '/' + path
return 'https://%s/%s%s%s' % (API_HOST, API_VERSION, path, '&' if '?' in path else '?') + 'output=xml'
def expect(condition, message):
if not condition:
raise Exception(message)
def verify_portfolio_xvf(portfolio_id, expected_portfolio_id, expected_lot_ids):
response = requests.get(get_url('/portfolio/%s' % portfolio_id), auth=auth, headers=headers)
response.raise_for_status()
xvf = xml.etree.ElementTree.fromstring(response.text)
portfolio = xvf.find('portfolio')
expect(xvf.attrib.get('version') == '1.20', 'Stored XVF version should be 1.20')
expect(portfolio is not None, 'Stored XVF is missing portfolio element')
expect(portfolio.attrib.get('portfolioid') == expected_portfolio_id,
'Stored portfolioid mismatch: %r' % portfolio.attrib.get('portfolioid'))
expect(portfolio.attrib.get('api-portfolioid') == portfolio_id,
'Stored api-portfolioid mismatch: %r' % portfolio.attrib.get('api-portfolioid'))
lots = {}
for lot in portfolio.findall('lot'):
lots[int(lot.attrib['number'])] = lot
for lot_number, lot_id in expected_lot_ids.items():
expect(lot_number in lots, 'Stored XVF is missing lot %d' % lot_number)
expect(lots[lot_number].attrib.get('lotid') == lot_id,
'Stored lotid mismatch for lot %d: %r' % (lot_number, lots[lot_number].attrib.get('lotid')))
return xvf
# Build the auth
auth = (API_TOKEN, API_KEY)
headers = {
'X-EVP-Actor-Email': API_ACTOR_EMAIL,
}
if API_ACTOR_WINDOWS_USER:
headers['X-EVP-Actor-Windows-User'] = API_ACTOR_WINDOWS_USER
# Create the portfolio -------------------------------------------------------
portfolio = """
"""
print('Creating the portfolio...')
try:
response = requests.post(get_url('/portfolio'), auth=auth, headers=headers, data=portfolio)
response.raise_for_status()
except Exception as e:
print(' FAILED (POST /portfolio error: %s)' % repr(e))
sys.exit(-1)
print(' Succeeded')
# Get the portfolio-id from the response -------------------------------------
print('Getting the portfolio-id...')
try:
document = get_document(response.text)
portfolio_id = document.find('portfolio-id').text
except Exception as e:
print(' FAILED (POST /portfolio response format error: %s)' % repr(e))
sys.exit(-1)
print(' Succeeded')
# Verify the stored XVF contains durable portfolio/lot ids -------------------
print('Verifying the stored portfolio ids...')
try:
verify_portfolio_xvf(portfolio_id, LOCAL_PORTFOLIO_ID, {1: LOT_IDS[1], 2: LOT_IDS[2], 4: LOT_IDS[4]})
except Exception as e:
print(' FAILED (GET /portfolio/{portfolio-id} identity verification error: %s)' % repr(e))
sys.exit(-1)
print(' Succeeded')
# Add and modify lots in the portfolio, using the portfolio-id ---------------
print('Updating lots in portfolio...')
portfolio = """
"""
try:
response = requests.put(get_url('/portfolio/%s' % portfolio_id), auth=auth, headers=headers, data=portfolio)
response.raise_for_status()
except Exception as e:
print(' FAILED (PUT /portfolio/{portfolio-id} error: %s)' % repr(e))
sys.exit(-1)
try:
document = get_document(response.text)
except Exception as e:
print(' FAILED (PUT /portfolio/{portfolio-id} response format error: %s)' % repr(e))
sys.exit(-1)
print(' Succeeded')
# Verify lotid preservation when lot number fallback is used -----------------
print('Verifying id preservation after update...')
try:
verify_portfolio_xvf(portfolio_id, LOCAL_PORTFOLIO_ID, LOT_IDS)
except Exception as e:
print(' FAILED (lotid preservation verification error: %s)' % repr(e))
sys.exit(-1)
print(' Succeeded')
# List the existing portfolios -----------------------------------------------
print('Listing the portfolios...')
try:
response = requests.get(get_url('/portfolio'), auth=auth, headers=headers, data=portfolio)
response.raise_for_status()
document = get_document(response.text)
for portfolio in document.iter('portfolio'):
print(' Portfolio: %s (ID %s, created %s)' % (portfolio.attrib.get('name', '[Unknown]'), portfolio.attrib['id'],
portfolio.attrib['portfolio_time_created']))
if document.find('more').text == 'true':
print(' ...and more')
except Exception as e:
print(' FAILED (GET /portfolio error: %s)' % repr(e))
sys.exit(-1)
print(' Succeeded')
# Start an evaluation of the portfolio, using the portfolio-id ---------------
print('Starting the report...')
try:
response = requests.post(get_url('/portfolio/%s/estateval/report?report=dod&file-name=%s' % (portfolio_id, INITIAL_REPORT_FILE_NAME)), auth=auth, headers=headers)
response.raise_for_status()
except Exception as e:
print(' FAILED (POST /portfolio/{portfolio-id}/estateval/report error: %s)' % repr(e))
sys.exit(-1)
print(' Succeeded')
# Get the report-id from the response ----------------------------------------
print('Getting the report-id...')
try:
document = get_document(response.text)
report_id = document.find('report-id').text
except Exception as e:
print(' FAILED (POST /portfolio/{portfolio-id}/estateval/report response format error: %s)' % repr(e))
sys.exit(-1)
print(' Succeeded')
# Poll the report-id for completion ------------------------------------------
print('Polling the report status...')
try:
while True:
response = requests.get(get_url('/portfolio/%s/estateval/report/%s/status' % (portfolio_id, report_id)), auth=auth, headers=headers)
response.raise_for_status()
document = get_document(response.text)
if document.find('status').text == 'ok':
break
print(' %03d%%: %s' % (int(document.find('pending-percent').text), document.find('pending-text').text))
time.sleep(1)
except Exception as e:
print(' FAILED (GET /portfolio/{portfolio-id}/estateval/report/{report-id}/status error: %s)' % repr(e))
sys.exit(-1)
print(' Succeeded')
# List the existing reports --------------------------------------------------
print('Listing the reports...')
try:
response = requests.get(get_url('/portfolio/%s/estateval/report' % portfolio_id), auth=auth, headers=headers, data=portfolio)
response.raise_for_status()
document = get_document(response.text)
for report in document.iter('report'):
print(' Report: %s for %s (ID %s, created %s)' % (report.attrib['type'], report.attrib['death-date'], report.attrib['id'],
report.attrib['report_time_created']))
if document.find('more').text == 'true':
print(' ...and more')
except Exception as e:
print(' FAILED (GET /portfolio/{portfolio-id}/estateval/report error: %s)' % repr(e))
sys.exit(-1)
print(' Succeeded')
# Get the report data --------------------------------------------------------
print('Getting the report data...')
try:
response = requests.get(get_url('/portfolio/%s/estateval/report/%s' % (portfolio_id, report_id)), auth=auth, headers=headers)
response.raise_for_status()
except Exception as e:
print(' FAILED (POST /portfolio/{portfolio-id}/estateval/report/{report-id} error: %s)' % repr(e))
sys.exit(-1)
print(' Succeeded')
print("\n%s" % response.text)
# Remove a lot and compact the remaining lot numbers ------------------------
print('Removing lot 2 and renumbering...')
portfolio = """
"""
try:
response = requests.put(get_url('/portfolio/%s?renumber=yes' % portfolio_id), auth=auth, headers=headers, data=portfolio)
response.raise_for_status()
document = get_document(response.text)
except Exception as e:
print(' FAILED (PUT /portfolio/{portfolio-id}?renumber=yes error: %s)' % repr(e))
sys.exit(-1)
print(' Succeeded')
print('Verifying renumbered lot order...')
try:
verify_portfolio_xvf(portfolio_id, LOCAL_PORTFOLIO_ID, {1: LOT_IDS[1], 2: LOT_IDS[3], 3: LOT_IDS[4]})
except Exception as e:
print(' FAILED (renumber verification error: %s)' % repr(e))
sys.exit(-1)
print(' Succeeded')
# Start a revised evaluation with a new File ID override --------------------
print('Starting the revised report...')
try:
response = requests.post(get_url('/portfolio/%s/estateval/report?report=dod&file-name=%s' % (portfolio_id, REVISED_REPORT_FILE_NAME)),
auth=auth, headers=headers)
response.raise_for_status()
except Exception as e:
print(' FAILED (POST revised /portfolio/{portfolio-id}/estateval/report error: %s)' % repr(e))
sys.exit(-1)
print(' Succeeded')
print('Getting the revised report-id...')
try:
document = get_document(response.text)
report_id = document.find('report-id').text
except Exception as e:
print(' FAILED (POST revised /portfolio/{portfolio-id}/estateval/report response format error: %s)' % repr(e))
sys.exit(-1)
print(' Succeeded')
print('Polling the revised report status...')
try:
while True:
response = requests.get(get_url('/portfolio/%s/estateval/report/%s/status' % (portfolio_id, report_id)), auth=auth, headers=headers)
response.raise_for_status()
document = get_document(response.text)
if document.find('status').text == 'ok':
break
print(' %03d%%: %s' % (int(document.find('pending-percent').text), document.find('pending-text').text))
time.sleep(1)
except Exception as e:
print(' FAILED (GET revised /portfolio/{portfolio-id}/estateval/report/{report-id}/status error: %s)' % repr(e))
sys.exit(-1)
print(' Succeeded')