Skip to content

Commit aa57eba

Browse files
authored
feat(fi): tests and examples (#11)
1 parent 1233e37 commit aa57eba

File tree

4 files changed

+208
-1
lines changed

4 files changed

+208
-1
lines changed

.gitignore

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ bld/
2323
[Bb]in/
2424
[Oo]bj/
2525
[Ll]og/
26+
*.tar.gz
2627

2728
# Visual Studio 2015 cache/options directory
2829
.vs/
@@ -260,4 +261,10 @@ paket-files/
260261

261262
# Python Tools for Visual Studio (PTVS)
262263
__pycache__/
263-
*.pyc
264+
*.pyc
265+
266+
# VSCode
267+
.vscode
268+
269+
# Python Environments
270+
env/

examples/fi_example.py

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
import json
2+
import sys
3+
import time
4+
import pandas as pd
5+
import uuid
6+
import os
7+
8+
from fds.analyticsapi.engines import ComponentSummary
9+
from fds.analyticsapi.engines.api.fi_calculations_api import FICalculationsApi
10+
from fds.analyticsapi.engines.api_client import ApiClient
11+
from fds.analyticsapi.engines.configuration import Configuration
12+
from fds.analyticsapi.engines.models.fi_calculation_parameters import FICalculationParameters
13+
from fds.analyticsapi.engines.models.security import Security
14+
from fds.analyticsapi.engines.models.job_settings import JobSettings
15+
from fds.analyticsapi.engines.stach_extensions import StachExtensions
16+
from fds.protobuf.stach.Package_pb2 import Package
17+
18+
from google.protobuf import json_format
19+
from google.protobuf.json_format import MessageToJson
20+
from google.protobuf.json_format import MessageToDict
21+
from urllib3 import Retry
22+
23+
host = "https://api.factset.com"
24+
username = os.environ["ANALYTICS_API_USERNAME_SERIAL"]
25+
password = os.environ["ANALYTICS_API_PASSWORD"]
26+
27+
def main():
28+
config = Configuration()
29+
config.host = host
30+
config.username = username
31+
config.password = password
32+
# add proxy and/or disable ssl verification according to your development environment
33+
# config.proxy = "<proxyUrl>"
34+
config.verify_ssl = False
35+
36+
# Setting configuration to retry api calls on http status codes of 429 and 503.
37+
config.retries = Retry(total=3, status=3, status_forcelist=frozenset([429, 503]), backoff_factor=2,
38+
raise_on_status=False)
39+
40+
api_client = ApiClient(config)
41+
42+
calculations = ["Security Type",
43+
"Security Name",
44+
"Run Status",
45+
"Elapse Time (seconds)",
46+
"Calc From Method",
47+
"Option Pricing Model",
48+
"Yield Curve Date",
49+
"Settlement Date",
50+
"Discount Curve",
51+
"Price",
52+
"Yield to No Call",
53+
"OAS",
54+
"Effective Duration",
55+
"Effective Convexity"]
56+
57+
security1 = Security("Price", 100.285, 10000.0, "912828ZG8", "20201202", "UST")
58+
security2 = Security("Price", 101.138, 200000.0, "US037833AR12", "20201203", "UST")
59+
60+
securities = [security1, security2]
61+
62+
jobSettings = JobSettings("20201201")
63+
64+
fi_calculation_parameters = FICalculationParameters(securities, calculations, jobSettings)
65+
66+
print(fi_calculation_parameters)
67+
68+
fi_calculations_api = FICalculationsApi(api_client)
69+
run_calculation_response = fi_calculations_api.run_fi_calculation_with_http_info(fi_calculation_parameters = fi_calculation_parameters)
70+
71+
if run_calculation_response[1] != 202 and run_calculation_response[1] != 201:
72+
print_error(run_calculation_response)
73+
sys.exit()
74+
75+
if run_calculation_response[1] == 201:
76+
print_result(run_calculation_response[0])
77+
sys.exit()
78+
79+
calculation_id = run_calculation_response[2].get("location").split("/")[-1]
80+
print("Calculation Id: " + calculation_id)
81+
82+
status_response = fi_calculations_api.get_fi_calculation_by_id_with_http_info(calculation_id)
83+
while status_response[1] == 202:
84+
max_age = '5'
85+
age_value = status_response[2].get("cache-control")
86+
if age_value is not None:
87+
max_age = age_value.replace("max-age=", "")
88+
print('Sleeping: ' + max_age)
89+
time.sleep(int(max_age))
90+
status_response = fi_calculations_api.get_fi_calculation_by_id_with_http_info(calculation_id)
91+
92+
if status_response[1] != 200:
93+
print_error(status_response)
94+
sys.exit()
95+
96+
print_result(status_response[0])
97+
98+
99+
def print_result(response):
100+
# converting the data to Package object
101+
result = json_format.Parse(json.dumps(response), Package())
102+
# print(MessageToJson(result)) # To print the result object as a JSON
103+
# print(MessageToDict(result)) # To print the result object as a Dictionary
104+
tables = StachExtensions.convert_to_table_format(result) # To convert result to 2D tables.
105+
print(tables[0]) # Prints the result in 2D table format.
106+
# generate_excel(result) # Uncomment this line to get the result in table format exported to excel file.
107+
108+
109+
def generate_excel(package):
110+
for table in StachExtensions.convert_to_table_format(package):
111+
writer = pd.ExcelWriter(str(uuid.uuid1()) + ".xlsx")
112+
table.to_excel(excel_writer=writer)
113+
writer.save()
114+
writer.close()
115+
116+
117+
def print_error(response):
118+
print("Calculation Failed!!!")
119+
print("Status Code: " + str(response[1]))
120+
print("Request Key: " + response[2].get("x-datadirect-request-key"))
121+
print(response[0])
122+
123+
124+
if __name__ == '__main__':
125+
main()

examples/requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fds.protobuf.stach <2.0.0

tests/test_fi_calculations_api.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import time
2+
import json
3+
import unittest
4+
import sys
5+
import uuid
6+
7+
from fds.analyticsapi.engines.api.fi_calculations_api import FICalculationsApi
8+
from fds.analyticsapi.engines.api_client import ApiClient
9+
from fds.analyticsapi.engines.configuration import Configuration
10+
from fds.analyticsapi.engines.models.fi_calculation_parameters import FICalculationParameters
11+
from fds.analyticsapi.engines.models.security import Security
12+
from fds.analyticsapi.engines.models.job_settings import JobSettings
13+
from fds.analyticsapi.engines.stach_extensions import StachExtensions
14+
from fds.protobuf.stach.Package_pb2 import Package
15+
16+
from google.protobuf import json_format
17+
from google.protobuf.json_format import MessageToJson
18+
from google.protobuf.json_format import MessageToDict
19+
20+
import common_parameters
21+
from common_functions import CommonFunctions
22+
23+
class TestFICalculationsApi(unittest.TestCase):
24+
25+
def setUp(self):
26+
self.api_client = CommonFunctions.build_api_client()
27+
self.calculations_api = FICalculationsApi(self.api_client)
28+
self.run_response = self.run_calculation()
29+
self.status_response = None
30+
31+
def run_calculation(self):
32+
calculations = ["Security Type",
33+
"Security Name",
34+
"Run Status",
35+
"Elapse Time (seconds)",
36+
"Calc From Method",
37+
"Option Pricing Model",
38+
"Yield Curve Date",
39+
"Settlement Date",
40+
"Discount Curve",
41+
"Price",
42+
"Yield to No Call",
43+
"OAS",
44+
"Effective Duration",
45+
"Effective Convexity"]
46+
47+
security1 = Security("Price", 100.285, 10000.0, "912828ZG8", "20201202", "UST")
48+
security2 = Security("Price", 101.138, 200000.0, "US037833AR12", "20201203", "UST")
49+
50+
securities = [security1, security2]
51+
52+
jobSettings = JobSettings("20201201")
53+
54+
fi_calculation_parameters = FICalculationParameters(securities, calculations, jobSettings)
55+
return self.calculations_api.run_fi_calculation_with_http_info(fi_calculation_parameters = fi_calculation_parameters)
56+
57+
def test_calculation_success(self):
58+
if(self.run_response[1] == 202):
59+
calculation_id = self.run_response[2].get("location").split("/")[-1]
60+
self.run_response = self.calculations_api.get_fi_calculation_by_id_with_http_info(calculation_id)
61+
while (self.run_response[1] == 202):
62+
age_value = self.run_response[2].get("cache-control")
63+
if age_value is not None:
64+
max_age = age_value.replace("max-age=", "")
65+
time.sleep(int(max_age))
66+
else:
67+
time.sleep(5)
68+
self.run_response = self.calculations_api.get_fi_calculation_by_id_with_http_info(calculation_id)
69+
70+
self.assertTrue(self.run_response[1] == 200 or self.run_response[1] == 201, "Calculation should be completed")
71+
72+
73+
if __name__ == '__main__':
74+
unittest.main()

0 commit comments

Comments
 (0)