finbourne-sdk-utils 0.0.24__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- features/__init__.py +0 -0
- features/main.py +11 -0
- finbourne_sdk_utils/__init__.py +8 -0
- finbourne_sdk_utils/cocoon/__init__.py +34 -0
- finbourne_sdk_utils/cocoon/async_tools.py +94 -0
- finbourne_sdk_utils/cocoon/cocoon.py +1862 -0
- finbourne_sdk_utils/cocoon/cocoon_printer.py +455 -0
- finbourne_sdk_utils/cocoon/config/domain_settings.json +125 -0
- finbourne_sdk_utils/cocoon/config/seed_sample_data.json +36 -0
- finbourne_sdk_utils/cocoon/dateorcutlabel.py +198 -0
- finbourne_sdk_utils/cocoon/instruments.py +482 -0
- finbourne_sdk_utils/cocoon/properties.py +442 -0
- finbourne_sdk_utils/cocoon/seed_sample_data.py +137 -0
- finbourne_sdk_utils/cocoon/systemConfiguration.py +92 -0
- finbourne_sdk_utils/cocoon/transaction_type_upload.py +136 -0
- finbourne_sdk_utils/cocoon/utilities.py +1877 -0
- finbourne_sdk_utils/cocoon/validator.py +243 -0
- finbourne_sdk_utils/extract/__init__.py +1 -0
- finbourne_sdk_utils/extract/group_holdings.py +400 -0
- finbourne_sdk_utils/iam/__init__.py +1 -0
- finbourne_sdk_utils/iam/roles.py +74 -0
- finbourne_sdk_utils/jupyter_tools/__init__.py +2 -0
- finbourne_sdk_utils/jupyter_tools/hide_code_button.py +23 -0
- finbourne_sdk_utils/jupyter_tools/stop_execution.py +14 -0
- finbourne_sdk_utils/logger/LusidLogger.py +41 -0
- finbourne_sdk_utils/logger/__init__.py +1 -0
- finbourne_sdk_utils/lpt/__init__.py +0 -0
- finbourne_sdk_utils/lpt/back_compat.py +20 -0
- finbourne_sdk_utils/lpt/cash_ladder.py +191 -0
- finbourne_sdk_utils/lpt/connect_lusid.py +64 -0
- finbourne_sdk_utils/lpt/connect_none.py +5 -0
- finbourne_sdk_utils/lpt/connect_token.py +9 -0
- finbourne_sdk_utils/lpt/dfq.py +321 -0
- finbourne_sdk_utils/lpt/either.py +65 -0
- finbourne_sdk_utils/lpt/get_instruments.py +101 -0
- finbourne_sdk_utils/lpt/lpt.py +374 -0
- finbourne_sdk_utils/lpt/lse.py +188 -0
- finbourne_sdk_utils/lpt/map_instruments.py +164 -0
- finbourne_sdk_utils/lpt/pager.py +32 -0
- finbourne_sdk_utils/lpt/record.py +13 -0
- finbourne_sdk_utils/lpt/refreshing_token.py +43 -0
- finbourne_sdk_utils/lpt/search_instruments.py +48 -0
- finbourne_sdk_utils/lpt/stdargs.py +154 -0
- finbourne_sdk_utils/lpt/txn_config.py +128 -0
- finbourne_sdk_utils/lpt/txn_config_yaml.py +493 -0
- finbourne_sdk_utils/pandas_utils/__init__.py +0 -0
- finbourne_sdk_utils/pandas_utils/lusid_pandas.py +128 -0
- finbourne_sdk_utils-0.0.24.dist-info/LICENSE +21 -0
- finbourne_sdk_utils-0.0.24.dist-info/METADATA +25 -0
- finbourne_sdk_utils-0.0.24.dist-info/RECORD +52 -0
- finbourne_sdk_utils-0.0.24.dist-info/WHEEL +5 -0
- finbourne_sdk_utils-0.0.24.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
import numpy as np
|
|
3
|
+
from finbourne_sdk_utils.cocoon import checkargs
|
|
4
|
+
from lusid.exceptions import ApiException
|
|
5
|
+
from flatten_json import flatten
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class CocoonPrinter:
|
|
9
|
+
VALID_KEYS = [
|
|
10
|
+
"portfolios",
|
|
11
|
+
"instruments",
|
|
12
|
+
"transactions",
|
|
13
|
+
"quotes",
|
|
14
|
+
"holdings",
|
|
15
|
+
"reference_portfolios",
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
def __init__(
|
|
19
|
+
self, response, extended_error_details=False, data_entity_details=False
|
|
20
|
+
):
|
|
21
|
+
self.validate(response)
|
|
22
|
+
|
|
23
|
+
self.response = response
|
|
24
|
+
self.file_type = list(response.keys())[0]
|
|
25
|
+
self.extended_error_details = extended_error_details
|
|
26
|
+
self.data_entity_details = data_entity_details
|
|
27
|
+
|
|
28
|
+
def validate(self, response):
|
|
29
|
+
if len(response.keys()) == 0:
|
|
30
|
+
message = (
|
|
31
|
+
f"Response doesn't contain any keys. Valid keys are {self.VALID_KEYS}"
|
|
32
|
+
)
|
|
33
|
+
raise ValueError(message)
|
|
34
|
+
|
|
35
|
+
if len(response.keys()) > 1:
|
|
36
|
+
message = f"Response contains too many keys - only one is allowed, but received {list(response.keys())}"
|
|
37
|
+
raise ValueError(message)
|
|
38
|
+
|
|
39
|
+
key = list(response.keys())[0]
|
|
40
|
+
|
|
41
|
+
if key not in self.VALID_KEYS:
|
|
42
|
+
message = f"Response contains invalid key. Valid keys are {self.VALID_KEYS}, but received {key}"
|
|
43
|
+
raise ValueError(message)
|
|
44
|
+
|
|
45
|
+
def format_instruments_response(self):
|
|
46
|
+
return format_instruments_response(
|
|
47
|
+
self.response,
|
|
48
|
+
extended_error_details=self.extended_error_details,
|
|
49
|
+
data_entity_details=self.data_entity_details,
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
def format_portfolios_response(self):
|
|
53
|
+
return format_portfolios_response(
|
|
54
|
+
self.response, extended_error_details=self.extended_error_details
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
def format_transactions_response(self):
|
|
58
|
+
return format_transactions_response(
|
|
59
|
+
self.response, extended_error_details=self.extended_error_details
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
def format_quotes_response(self):
|
|
63
|
+
return format_quotes_response(
|
|
64
|
+
self.response, extended_error_details=self.extended_error_details,
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
def format_holdings_response(self):
|
|
68
|
+
return format_holdings_response(
|
|
69
|
+
self.response, extended_error_details=self.extended_error_details,
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
def format_reference_portfolios_response(self):
|
|
73
|
+
return format_reference_portfolios_response(
|
|
74
|
+
self.response, extended_error_details=self.extended_error_details,
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
def format_response(self):
|
|
78
|
+
return getattr(CocoonPrinter, f"format_{self.file_type}_response")(self)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@checkargs
|
|
82
|
+
def check_dict_for_required_keys(
|
|
83
|
+
target_dict: dict, target_name: str, required_keys: list
|
|
84
|
+
):
|
|
85
|
+
"""
|
|
86
|
+
This function checks that a named dictionary contains a list of required key
|
|
87
|
+
|
|
88
|
+
Parameters
|
|
89
|
+
----------
|
|
90
|
+
target_dict : dict
|
|
91
|
+
Dictionary to check for keys in
|
|
92
|
+
target_name : str
|
|
93
|
+
Variable name of dictionary
|
|
94
|
+
required_keys : list
|
|
95
|
+
List of required keys
|
|
96
|
+
|
|
97
|
+
Returns
|
|
98
|
+
-------
|
|
99
|
+
None
|
|
100
|
+
"""
|
|
101
|
+
|
|
102
|
+
for key in required_keys:
|
|
103
|
+
if key not in target_dict.keys():
|
|
104
|
+
raise ValueError(
|
|
105
|
+
f"'{key}' missing from {target_name}. {target_name} must include {required_keys}"
|
|
106
|
+
f"as keys"
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def get_errors_from_response(
|
|
111
|
+
list_of_API_exceptions: list, extended_error_details: bool = False
|
|
112
|
+
):
|
|
113
|
+
"""
|
|
114
|
+
This function gets the status code and reason from API exception
|
|
115
|
+
|
|
116
|
+
Parameters
|
|
117
|
+
----------
|
|
118
|
+
list_of_API_exceptions : list
|
|
119
|
+
A list of ApiExceptions
|
|
120
|
+
extended_error_details : bool
|
|
121
|
+
A flag that determines whether the errors returned will have extended details (request id, error body)
|
|
122
|
+
Returns
|
|
123
|
+
-------
|
|
124
|
+
pd.DataFrame
|
|
125
|
+
A Pandas DataFrame containing the reasons and status codes for ApiExceptions from a request.
|
|
126
|
+
If the extended_error_details bool is True, the RequestID and error body will also be returned.
|
|
127
|
+
"""
|
|
128
|
+
|
|
129
|
+
# check all items are ApiExceptions
|
|
130
|
+
for i in list_of_API_exceptions:
|
|
131
|
+
if not isinstance(i, ApiException):
|
|
132
|
+
raise TypeError(
|
|
133
|
+
f" Unexpected Error in response. Expected instance of ApiException, but got: {repr(i)}"
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
# get status and reason for each batch
|
|
137
|
+
status = [item.status for item in list_of_API_exceptions]
|
|
138
|
+
reason = [item.reason for item in list_of_API_exceptions]
|
|
139
|
+
|
|
140
|
+
items_list = [reason, status]
|
|
141
|
+
column_names = ["error_items", "status"]
|
|
142
|
+
|
|
143
|
+
if extended_error_details:
|
|
144
|
+
request_id = [
|
|
145
|
+
item.headers.get("lusid-meta-requestId") for item in list_of_API_exceptions
|
|
146
|
+
]
|
|
147
|
+
error_body = [item.body for item in list_of_API_exceptions]
|
|
148
|
+
items_list.extend([request_id, error_body])
|
|
149
|
+
column_names.extend(["request_id", "error_body"])
|
|
150
|
+
|
|
151
|
+
# transpose list of lists for insertion to dataframe
|
|
152
|
+
items_error = np.array(items_list).T.tolist()
|
|
153
|
+
|
|
154
|
+
return pd.DataFrame(items_error, columns=column_names)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def get_portfolio_from_href(href: list, file_type: str):
|
|
158
|
+
"""
|
|
159
|
+
This function finds the protfolio code contained within a href for a given file_type
|
|
160
|
+
|
|
161
|
+
Parameters
|
|
162
|
+
----------
|
|
163
|
+
href : list
|
|
164
|
+
list of hrefs from LUSID response
|
|
165
|
+
file_type : str
|
|
166
|
+
|
|
167
|
+
Returns
|
|
168
|
+
-------
|
|
169
|
+
list
|
|
170
|
+
portfolio codes taken from hrefs
|
|
171
|
+
"""
|
|
172
|
+
|
|
173
|
+
# get portfolio codes from each href
|
|
174
|
+
codes = [j[-2] for j in [i.split("/") for i in href]]
|
|
175
|
+
|
|
176
|
+
return codes
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
@checkargs
|
|
180
|
+
def get_non_href_response(response: dict, file_type: str, data_entity_details=False):
|
|
181
|
+
dict_items_success = [
|
|
182
|
+
(key, value)
|
|
183
|
+
for batch in response[file_type]["success"]
|
|
184
|
+
for (key, value) in batch.values.items()
|
|
185
|
+
]
|
|
186
|
+
dict_items_failed = [
|
|
187
|
+
(key, value)
|
|
188
|
+
for batch in response[file_type]["success"]
|
|
189
|
+
for (key, value) in batch.failed.items()
|
|
190
|
+
]
|
|
191
|
+
|
|
192
|
+
def extract_value_details_from_success_request(data_entity_dict):
|
|
193
|
+
return pd.DataFrame(
|
|
194
|
+
flatten(value[1].to_dict(), ".") for value in data_entity_dict
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
def extract_key_details_from_success_request(data_entity_dict):
|
|
198
|
+
return pd.DataFrame(value[0] for value in data_entity_dict)
|
|
199
|
+
|
|
200
|
+
if data_entity_details:
|
|
201
|
+
|
|
202
|
+
return (
|
|
203
|
+
extract_value_details_from_success_request(dict_items_success),
|
|
204
|
+
extract_value_details_from_success_request(dict_items_failed),
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
else:
|
|
208
|
+
|
|
209
|
+
return (
|
|
210
|
+
extract_key_details_from_success_request(dict_items_success),
|
|
211
|
+
extract_key_details_from_success_request(dict_items_failed),
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def format_instruments_response(
|
|
216
|
+
response: dict,
|
|
217
|
+
extended_error_details: bool = False,
|
|
218
|
+
data_entity_details: bool = False,
|
|
219
|
+
) -> tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]:
|
|
220
|
+
"""
|
|
221
|
+
This function unpacks a response from instrument requests and returns successful, failed and errored statuses for
|
|
222
|
+
request constituents.
|
|
223
|
+
Parameters
|
|
224
|
+
----------
|
|
225
|
+
response : dict
|
|
226
|
+
response from Lusid-python-tools
|
|
227
|
+
extended_error_details : bool
|
|
228
|
+
A flag that determines whether the errors returned will have extended details (request id, error body)
|
|
229
|
+
data_entity_details : bool
|
|
230
|
+
A flag that determines whether the fields from the response will all be extracted
|
|
231
|
+
Returns
|
|
232
|
+
-------
|
|
233
|
+
success : pd.DataFrame
|
|
234
|
+
successful calls from request
|
|
235
|
+
error : pd.DataFrame
|
|
236
|
+
Error responses from request that fail (APIExceptions: 400 errors)
|
|
237
|
+
fail : pd.Dataframe
|
|
238
|
+
Failed responses that LUSID rejected
|
|
239
|
+
"""
|
|
240
|
+
|
|
241
|
+
file_type = "instruments"
|
|
242
|
+
check_dict_for_required_keys(
|
|
243
|
+
response[file_type], f"Response from {file_type} request", ["errors", "success"]
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
# get success and failures
|
|
247
|
+
items_success, items_failed = get_non_href_response(
|
|
248
|
+
response, file_type, data_entity_details
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
return (
|
|
252
|
+
items_success,
|
|
253
|
+
get_errors_from_response(response[file_type]["errors"], extended_error_details),
|
|
254
|
+
items_failed,
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
def format_portfolios_response(
|
|
259
|
+
response: dict, extended_error_details: bool = False,
|
|
260
|
+
) -> tuple[pd.DataFrame, pd.DataFrame]:
|
|
261
|
+
"""
|
|
262
|
+
This function unpacks a response from portfolio requests and returns successful and errored statuses for
|
|
263
|
+
request constituents.
|
|
264
|
+
|
|
265
|
+
Parameters
|
|
266
|
+
----------
|
|
267
|
+
response : dict
|
|
268
|
+
response from Lusid-python-tools
|
|
269
|
+
extended_error_details : bool
|
|
270
|
+
A flag that determines whether the errors returned will have extended details (request id, error body)
|
|
271
|
+
|
|
272
|
+
Returns
|
|
273
|
+
-------
|
|
274
|
+
success : pd.DataFrame
|
|
275
|
+
successful calls from request
|
|
276
|
+
error : pd.DataFrame
|
|
277
|
+
Error responses from request that fail (APIExceptions: 400 errors)
|
|
278
|
+
"""
|
|
279
|
+
file_type = "portfolios"
|
|
280
|
+
check_dict_for_required_keys(
|
|
281
|
+
response[file_type], f"Response from {file_type} request", ["errors", "success"]
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
# get success
|
|
285
|
+
items_success = [batch.id.code for batch in response[file_type]["success"]]
|
|
286
|
+
|
|
287
|
+
errors = get_errors_from_response(
|
|
288
|
+
response[file_type]["errors"], extended_error_details
|
|
289
|
+
)
|
|
290
|
+
|
|
291
|
+
return (pd.DataFrame(items_success, columns=["successful items"]), errors)
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
def format_transactions_response(
|
|
295
|
+
response: dict, extended_error_details: bool = False,
|
|
296
|
+
) -> tuple[pd.DataFrame, pd.DataFrame]:
|
|
297
|
+
"""
|
|
298
|
+
This function unpacks a response from transaction requests and returns successful and errored statuses for
|
|
299
|
+
request constituents.
|
|
300
|
+
|
|
301
|
+
Parameters
|
|
302
|
+
----------
|
|
303
|
+
response : dict
|
|
304
|
+
response from Lusid-python-tools
|
|
305
|
+
extended_error_details : bool
|
|
306
|
+
A flag that determines whether the errors returned will have extended details (request id, error body)
|
|
307
|
+
|
|
308
|
+
Returns
|
|
309
|
+
-------
|
|
310
|
+
success : pd.DataFrame
|
|
311
|
+
successful calls from request
|
|
312
|
+
error : pd.DataFrame
|
|
313
|
+
Error responses from request that fail (APIExceptions: 400 errors)
|
|
314
|
+
"""
|
|
315
|
+
|
|
316
|
+
file_type = "transactions"
|
|
317
|
+
|
|
318
|
+
check_dict_for_required_keys(
|
|
319
|
+
response[file_type], f"Response from {file_type} request", ["errors", "success"]
|
|
320
|
+
)
|
|
321
|
+
|
|
322
|
+
# get success
|
|
323
|
+
items_success = [batch.href for batch in response[file_type]["success"]]
|
|
324
|
+
|
|
325
|
+
errors = get_errors_from_response(
|
|
326
|
+
response[file_type]["errors"], extended_error_details
|
|
327
|
+
)
|
|
328
|
+
|
|
329
|
+
return (
|
|
330
|
+
pd.DataFrame(
|
|
331
|
+
get_portfolio_from_href(items_success, file_type),
|
|
332
|
+
columns=["successful items"],
|
|
333
|
+
),
|
|
334
|
+
errors,
|
|
335
|
+
)
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
def format_holdings_response(
|
|
339
|
+
response: dict, extended_error_details: bool = False,
|
|
340
|
+
) -> tuple[pd.DataFrame, pd.DataFrame]:
|
|
341
|
+
"""
|
|
342
|
+
This function unpacks a response from holding requests and returns successful and errored statuses for
|
|
343
|
+
request constituents.
|
|
344
|
+
|
|
345
|
+
Parameters
|
|
346
|
+
----------
|
|
347
|
+
response : dict
|
|
348
|
+
response from Lusid-python-tools
|
|
349
|
+
extended_error_details : bool
|
|
350
|
+
A flag that determines whether the errors returned will have extended details (request id, error body)
|
|
351
|
+
|
|
352
|
+
Returns
|
|
353
|
+
-------
|
|
354
|
+
success : pd.DataFrame
|
|
355
|
+
successful calls from request
|
|
356
|
+
error : pd.DataFrame
|
|
357
|
+
Error responses from request that fail (APIExceptions: 400 errors)
|
|
358
|
+
|
|
359
|
+
"""
|
|
360
|
+
|
|
361
|
+
file_type = "holdings"
|
|
362
|
+
check_dict_for_required_keys(
|
|
363
|
+
response[file_type], f"Response from {file_type} request", ["errors", "success"]
|
|
364
|
+
)
|
|
365
|
+
|
|
366
|
+
# get success
|
|
367
|
+
items_success = [batch.href for batch in response[file_type]["success"]]
|
|
368
|
+
|
|
369
|
+
errors = get_errors_from_response(
|
|
370
|
+
response[file_type]["errors"], extended_error_details
|
|
371
|
+
)
|
|
372
|
+
|
|
373
|
+
return (
|
|
374
|
+
pd.DataFrame(
|
|
375
|
+
get_portfolio_from_href(items_success, file_type),
|
|
376
|
+
columns=["successful items"],
|
|
377
|
+
),
|
|
378
|
+
errors,
|
|
379
|
+
)
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
def format_quotes_response(
|
|
383
|
+
response: dict, extended_error_details: bool = False,
|
|
384
|
+
) -> tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]:
|
|
385
|
+
"""
|
|
386
|
+
This function unpacks a response from quotes requests and returns successful, failed and errored statuses for
|
|
387
|
+
request constituents.
|
|
388
|
+
|
|
389
|
+
Parameters
|
|
390
|
+
----------
|
|
391
|
+
response : dict
|
|
392
|
+
response from Lusid-python-tools
|
|
393
|
+
extended_error_details : bool
|
|
394
|
+
A flag that determines whether the errors returned will have extended details (request id, error body)
|
|
395
|
+
|
|
396
|
+
Returns
|
|
397
|
+
-------
|
|
398
|
+
success : pd.DataFrame
|
|
399
|
+
successful calls from request
|
|
400
|
+
error : pd.DataFrame
|
|
401
|
+
Error responses from request that fail (APIExceptions: 400 errors)
|
|
402
|
+
fail : pd.Dataframe
|
|
403
|
+
Failed responses that LUSID rejected
|
|
404
|
+
"""
|
|
405
|
+
|
|
406
|
+
file_type = "quotes"
|
|
407
|
+
|
|
408
|
+
check_dict_for_required_keys(
|
|
409
|
+
response[file_type], f"Response from {file_type} request", ["errors", "success"]
|
|
410
|
+
)
|
|
411
|
+
items_success, items_failed = get_non_href_response(
|
|
412
|
+
response, file_type, data_entity_details=True
|
|
413
|
+
)
|
|
414
|
+
|
|
415
|
+
return (
|
|
416
|
+
items_success,
|
|
417
|
+
get_errors_from_response(response[file_type]["errors"], extended_error_details),
|
|
418
|
+
items_failed,
|
|
419
|
+
)
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
def format_reference_portfolios_response(
|
|
423
|
+
response: dict, extended_error_details: bool = False,
|
|
424
|
+
) -> tuple[pd.DataFrame, pd.DataFrame]:
|
|
425
|
+
"""
|
|
426
|
+
This function unpacks a response from reference portfolio requests and returns successful and errored statuses for request constituents.
|
|
427
|
+
|
|
428
|
+
Parameters
|
|
429
|
+
----------
|
|
430
|
+
response : dict
|
|
431
|
+
response from Lusid-python-tools
|
|
432
|
+
extended_error_details : bool
|
|
433
|
+
A flag that determines whether the errors returned will have extended details (request id, error body)
|
|
434
|
+
|
|
435
|
+
Returns
|
|
436
|
+
-------
|
|
437
|
+
success : pd.DataFrame
|
|
438
|
+
successful calls from request
|
|
439
|
+
error : pd.DataFrame
|
|
440
|
+
Error responses from rquest that fail (APIExceptions: 400 errors)
|
|
441
|
+
"""
|
|
442
|
+
|
|
443
|
+
file_type = "reference_portfolios"
|
|
444
|
+
check_dict_for_required_keys(
|
|
445
|
+
response[file_type], f"Response from {file_type} request", ["errors", "success"]
|
|
446
|
+
)
|
|
447
|
+
|
|
448
|
+
# get success
|
|
449
|
+
items_success = [batch.id.code for batch in response[file_type]["success"]]
|
|
450
|
+
|
|
451
|
+
errors = get_errors_from_response(
|
|
452
|
+
response[file_type]["errors"], extended_error_details
|
|
453
|
+
)
|
|
454
|
+
|
|
455
|
+
return (pd.DataFrame(items_success, columns=["successful items"]), errors)
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
{
|
|
2
|
+
"transaction": {
|
|
3
|
+
"domain": "Transaction",
|
|
4
|
+
"batch_allowed": true,
|
|
5
|
+
"default_batch_size": 10000,
|
|
6
|
+
"top_level_model": "TransactionRequest",
|
|
7
|
+
"portfolio_specific": true,
|
|
8
|
+
"full_key_format": true,
|
|
9
|
+
"required_call_attributes": [
|
|
10
|
+
"scope",
|
|
11
|
+
"code"
|
|
12
|
+
],
|
|
13
|
+
"unique_attributes": [
|
|
14
|
+
"transaction_id"
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
"transactions_with_commit_mode": {
|
|
18
|
+
"domain": "Transaction",
|
|
19
|
+
"batch_allowed": true,
|
|
20
|
+
"default_batch_size": 10000,
|
|
21
|
+
"top_level_model": "TransactionRequest",
|
|
22
|
+
"portfolio_specific": true,
|
|
23
|
+
"full_key_format": true,
|
|
24
|
+
"required_call_attributes": [
|
|
25
|
+
"scope",
|
|
26
|
+
"code"
|
|
27
|
+
],
|
|
28
|
+
"unique_attributes": [
|
|
29
|
+
"transaction_id"
|
|
30
|
+
]
|
|
31
|
+
},
|
|
32
|
+
"holding": {
|
|
33
|
+
"domain": "Holding",
|
|
34
|
+
"default_batch_size": 100000000000,
|
|
35
|
+
"batch_allowed": false,
|
|
36
|
+
"top_level_model": "AdjustHoldingRequest",
|
|
37
|
+
"portfolio_specific": true,
|
|
38
|
+
"full_key_format": true,
|
|
39
|
+
"required_call_attributes": [
|
|
40
|
+
"scope",
|
|
41
|
+
"code",
|
|
42
|
+
"effective_at"
|
|
43
|
+
],
|
|
44
|
+
"unique_attributes": [
|
|
45
|
+
"effective_at"
|
|
46
|
+
]
|
|
47
|
+
},
|
|
48
|
+
"instrument": {
|
|
49
|
+
"domain": "Instrument",
|
|
50
|
+
"batch_allowed": true,
|
|
51
|
+
"default_batch_size": 2000,
|
|
52
|
+
"top_level_model": "InstrumentDefinition",
|
|
53
|
+
"portfolio_specific": false,
|
|
54
|
+
"full_key_format": false,
|
|
55
|
+
"required_call_attributes": [],
|
|
56
|
+
"unique_attributes": []
|
|
57
|
+
},
|
|
58
|
+
"portfolio": {
|
|
59
|
+
"domain": "Portfolio",
|
|
60
|
+
"batch_allowed": false,
|
|
61
|
+
"default_batch_size": 100000000000,
|
|
62
|
+
"top_level_model": "CreateTransactionPortfolioRequest",
|
|
63
|
+
"portfolio_specific": true,
|
|
64
|
+
"full_key_format": false,
|
|
65
|
+
"required_call_attributes": [
|
|
66
|
+
"scope",
|
|
67
|
+
"code"
|
|
68
|
+
],
|
|
69
|
+
"unique_attributes": [
|
|
70
|
+
"code"
|
|
71
|
+
]
|
|
72
|
+
},
|
|
73
|
+
"quote": {
|
|
74
|
+
"domain": null,
|
|
75
|
+
"batch_allowed": true,
|
|
76
|
+
"default_batch_size": 2000,
|
|
77
|
+
"top_level_model": "UpsertQuoteRequest",
|
|
78
|
+
"portfolio_specific": false,
|
|
79
|
+
"full_key_format": false,
|
|
80
|
+
"required_call_attributes": [
|
|
81
|
+
"scope"
|
|
82
|
+
],
|
|
83
|
+
"unique_attributes": []
|
|
84
|
+
},
|
|
85
|
+
"instrument_property": {
|
|
86
|
+
"domain": "Instrument",
|
|
87
|
+
"batch_allowed": true,
|
|
88
|
+
"default_batch_size": 2000,
|
|
89
|
+
"top_level_model": "UpsertInstrumentPropertyRequest",
|
|
90
|
+
"portfolio_specific": false,
|
|
91
|
+
"full_key_format": false,
|
|
92
|
+
"required_call_attributes": [],
|
|
93
|
+
"unique_attributes": []
|
|
94
|
+
},
|
|
95
|
+
"portfolio_group": {
|
|
96
|
+
"domain": "PortfolioGroup",
|
|
97
|
+
"batch_allowed": true,
|
|
98
|
+
"default_batch_size": 2000,
|
|
99
|
+
"top_level_model": "CreatePortfolioGroupRequest",
|
|
100
|
+
"portfolio_specific": true,
|
|
101
|
+
"full_key_format": false,
|
|
102
|
+
"required_call_attributes": [
|
|
103
|
+
"scope",
|
|
104
|
+
"code"
|
|
105
|
+
],
|
|
106
|
+
"unique_attributes": [
|
|
107
|
+
"code"
|
|
108
|
+
]
|
|
109
|
+
},
|
|
110
|
+
"reference_portfolio": {
|
|
111
|
+
"domain": "Portfolio",
|
|
112
|
+
"batch_allowed": false,
|
|
113
|
+
"default_batch_size": 2000,
|
|
114
|
+
"top_level_model": "CreateReferencePortfolioRequest",
|
|
115
|
+
"portfolio_specific": true,
|
|
116
|
+
"full_key_format": false,
|
|
117
|
+
"required_call_attributes": [
|
|
118
|
+
"scope",
|
|
119
|
+
"code"
|
|
120
|
+
],
|
|
121
|
+
"unique_attributes": [
|
|
122
|
+
"code"
|
|
123
|
+
]
|
|
124
|
+
}
|
|
125
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{"instruments": {
|
|
2
|
+
"identifier_mapping": {
|
|
3
|
+
"ClientInternal": "instrument_id",
|
|
4
|
+
"Ticker": "ticker",
|
|
5
|
+
"Sedol": "sedol"},
|
|
6
|
+
"required": {"name": "name"},
|
|
7
|
+
"properties": ["instrument_type"],
|
|
8
|
+
"optional": {}
|
|
9
|
+
},"portfolios": {
|
|
10
|
+
"required": {
|
|
11
|
+
"code": "portfolio_code",
|
|
12
|
+
"display_name": "portfolio_name",
|
|
13
|
+
"base_currency": "portfolio_base_currency"
|
|
14
|
+
},
|
|
15
|
+
"optional": {"created": "$2000-01-01T00:00:00+00:00"},
|
|
16
|
+
"identifier_mapping" : {},
|
|
17
|
+
"properties": []
|
|
18
|
+
},"transactions":
|
|
19
|
+
{"identifier_mapping": {
|
|
20
|
+
"ClientInternal": "instrument_id",
|
|
21
|
+
"Currency": "cash_transactions"
|
|
22
|
+
},
|
|
23
|
+
"required": {
|
|
24
|
+
"code": "portfolio_code",
|
|
25
|
+
"transaction_id": "txn_id",
|
|
26
|
+
"type": "txn_type",
|
|
27
|
+
"transaction_price.price": "txn_price",
|
|
28
|
+
"transaction_price.type": "$Price",
|
|
29
|
+
"total_consideration.amount": "txn_consideration",
|
|
30
|
+
"units": "txn_units",
|
|
31
|
+
"transaction_date": "txn_trade_date",
|
|
32
|
+
"total_consideration.currency": "currency",
|
|
33
|
+
"settlement_date": "txn_settle_date"
|
|
34
|
+
},
|
|
35
|
+
"optional": {},
|
|
36
|
+
"properties": ["strategy"]}}
|