#!/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')