lusid-sdk 2.1.405__py3-none-any.whl → 2.1.537__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.
Files changed (294) hide show
  1. lusid/__init__.py +142 -8
  2. lusid/api/__init__.py +2 -2
  3. lusid/api/abor_api.py +126 -133
  4. lusid/api/abor_configuration_api.py +46 -45
  5. lusid/api/address_key_definition_api.py +28 -27
  6. lusid/api/aggregation_api.py +37 -36
  7. lusid/api/allocations_api.py +39 -38
  8. lusid/api/amortisation_rule_sets_api.py +55 -54
  9. lusid/api/application_metadata_api.py +28 -27
  10. lusid/api/blocks_api.py +37 -36
  11. lusid/api/calendars_api.py +469 -111
  12. lusid/api/chart_of_accounts_api.py +454 -279
  13. lusid/api/complex_market_data_api.py +37 -36
  14. lusid/api/compliance_api.py +136 -135
  15. lusid/api/configuration_recipe_api.py +100 -99
  16. lusid/api/conventions_api.py +109 -108
  17. lusid/api/corporate_action_sources_api.py +82 -81
  18. lusid/api/counterparties_api.py +73 -72
  19. lusid/api/custom_entities_api.py +102 -101
  20. lusid/api/custom_entity_definitions_api.py +37 -36
  21. lusid/api/custom_entity_types_api.py +37 -36
  22. lusid/api/cut_label_definitions_api.py +46 -45
  23. lusid/api/data_types_api.py +248 -72
  24. lusid/api/derived_transaction_portfolios_api.py +19 -18
  25. lusid/api/entities_api.py +431 -46
  26. lusid/api/executions_api.py +37 -36
  27. lusid/api/fee_types_api.py +55 -54
  28. lusid/api/{fund_configurations_api.py → fund_configuration_api.py} +222 -46
  29. lusid/api/funds_api.py +337 -162
  30. lusid/api/group_reconciliations_api.py +2182 -63
  31. lusid/api/instrument_event_types_api.py +64 -63
  32. lusid/api/instrument_events_api.py +46 -45
  33. lusid/api/instruments_api.py +374 -186
  34. lusid/api/legacy_compliance_api.py +73 -72
  35. lusid/api/legal_entities_api.py +167 -166
  36. lusid/api/order_graph_api.py +32 -31
  37. lusid/api/order_instructions_api.py +37 -36
  38. lusid/api/order_management_api.py +251 -90
  39. lusid/api/orders_api.py +37 -36
  40. lusid/api/packages_api.py +37 -36
  41. lusid/api/participations_api.py +37 -36
  42. lusid/api/persons_api.py +163 -162
  43. lusid/api/placements_api.py +37 -36
  44. lusid/api/portfolio_groups_api.py +235 -234
  45. lusid/api/portfolios_api.py +307 -309
  46. lusid/api/property_definitions_api.py +100 -99
  47. lusid/api/queryable_keys_api.py +10 -9
  48. lusid/api/quotes_api.py +82 -81
  49. lusid/api/reconciliations_api.py +136 -135
  50. lusid/api/reference_lists_api.py +39 -38
  51. lusid/api/reference_portfolio_api.py +213 -36
  52. lusid/api/relation_definitions_api.py +28 -27
  53. lusid/api/relations_api.py +19 -18
  54. lusid/api/relationship_definitions_api.py +46 -45
  55. lusid/api/relationships_api.py +19 -18
  56. lusid/api/schemas_api.py +37 -36
  57. lusid/api/scopes_api.py +19 -18
  58. lusid/api/scripted_translation_api.py +73 -72
  59. lusid/api/search_api.py +37 -36
  60. lusid/api/sequences_api.py +37 -36
  61. lusid/api/staged_modifications_api.py +37 -36
  62. lusid/api/staging_rule_set_api.py +46 -45
  63. lusid/api/structured_result_data_api.py +82 -81
  64. lusid/api/system_configuration_api.py +64 -63
  65. lusid/api/tax_rule_sets_api.py +46 -45
  66. lusid/api/transaction_configuration_api.py +100 -99
  67. lusid/api/transaction_fees_api.py +46 -45
  68. lusid/api/transaction_portfolios_api.py +771 -328
  69. lusid/api/translation_api.py +19 -18
  70. lusid/api/workspace_api.py +181 -180
  71. lusid/api_client.py +26 -17
  72. lusid/configuration.py +87 -2
  73. lusid/extensions/api_client.py +25 -17
  74. lusid/extensions/api_client_factory.py +14 -5
  75. lusid/extensions/api_configuration.py +50 -1
  76. lusid/extensions/configuration_loaders.py +39 -11
  77. lusid/extensions/configuration_options.py +67 -0
  78. lusid/extensions/rest.py +78 -26
  79. lusid/extensions/retry.py +109 -37
  80. lusid/models/__init__.py +140 -6
  81. lusid/models/access_metadata_value.py +1 -1
  82. lusid/models/accounting_method.py +7 -0
  83. lusid/models/accumulation_event.py +3 -3
  84. lusid/models/address_key_list.py +3 -3
  85. lusid/models/amortisation_event.py +3 -3
  86. lusid/models/amount.py +69 -0
  87. lusid/models/applicable_instrument_event.py +7 -2
  88. lusid/models/asset_leg.py +1 -1
  89. lusid/models/basket.py +3 -3
  90. lusid/models/batch_update_user_review_for_comparison_result_request.py +81 -0
  91. lusid/models/batch_update_user_review_for_comparison_result_response.py +146 -0
  92. lusid/models/batch_upsert_dates_for_calendar_response.py +146 -0
  93. lusid/models/batch_upsert_portfolio_access_metadata_request.py +27 -17
  94. lusid/models/batch_upsert_portfolio_access_metadata_response.py +56 -16
  95. lusid/models/{metadata_key_value.py → batch_upsert_portfolio_access_metadata_response_item.py} +15 -9
  96. lusid/models/bond.py +3 -3
  97. lusid/models/bond_coupon_event.py +10 -5
  98. lusid/models/bond_default_event.py +3 -3
  99. lusid/models/bond_principal_event.py +10 -5
  100. lusid/models/bonus_issue_event.py +166 -0
  101. lusid/models/{component_rule.py → break_code_source.py} +17 -21
  102. lusid/models/call_on_intermediate_securities_event.py +139 -0
  103. lusid/models/cancel_order_and_move_remaining_result.py +84 -0
  104. lusid/models/cancel_orders_and_move_remaining_request.py +83 -0
  105. lusid/models/cancel_orders_and_move_remaining_response.py +153 -0
  106. lusid/models/cap_floor.py +3 -3
  107. lusid/models/capital_distribution_event.py +3 -3
  108. lusid/models/cash.py +3 -3
  109. lusid/models/cash_dividend_event.py +3 -3
  110. lusid/models/cash_flow_event.py +3 -3
  111. lusid/models/cash_perpetual.py +3 -3
  112. lusid/models/cds_credit_event.py +6 -6
  113. lusid/models/cds_index.py +3 -3
  114. lusid/models/cdx_credit_event.py +6 -6
  115. lusid/models/change_interval.py +123 -0
  116. lusid/models/change_interval_with_order_management_detail.py +3 -3
  117. lusid/models/close_event.py +3 -3
  118. lusid/models/comparison_attribute_value_pair.py +71 -0
  119. lusid/models/complex_bond.py +3 -3
  120. lusid/models/component_transaction.py +10 -3
  121. lusid/models/contract_for_difference.py +3 -3
  122. lusid/models/create_derived_transaction_portfolio_request.py +3 -3
  123. lusid/models/create_group_reconciliation_definition_request.py +113 -0
  124. lusid/models/create_staging_rule_set_request.py +1 -6
  125. lusid/models/create_transaction_portfolio_request.py +3 -3
  126. lusid/models/credit_default_swap.py +3 -3
  127. lusid/models/credit_premium_cash_flow_event.py +3 -3
  128. lusid/models/custodian_account_request.py +1 -1
  129. lusid/models/custom_entity_entity.py +146 -0
  130. lusid/models/custom_entity_response.py +7 -1
  131. lusid/models/decimal_list.py +3 -3
  132. lusid/models/delete_instrument_properties_response.py +7 -1
  133. lusid/models/delete_instrument_response.py +7 -1
  134. lusid/models/delete_instruments_response.py +22 -1
  135. lusid/models/deleted_entity_response.py +7 -1
  136. lusid/models/diary_entry_request.py +10 -1
  137. lusid/models/dividend_option_event.py +3 -3
  138. lusid/models/dividend_reinvestment_event.py +9 -4
  139. lusid/models/effective_range.py +71 -0
  140. lusid/models/equity.py +3 -3
  141. lusid/models/equity_option.py +22 -7
  142. lusid/models/equity_swap.py +3 -3
  143. lusid/models/exchange_traded_option.py +3 -3
  144. lusid/models/exchange_traded_option_contract_details.py +1 -1
  145. lusid/models/exercise_event.py +3 -3
  146. lusid/models/exotic_instrument.py +3 -3
  147. lusid/models/expiry_event.py +3 -3
  148. lusid/models/fee.py +17 -10
  149. lusid/models/fee_request.py +20 -13
  150. lusid/models/fee_type.py +4 -4
  151. lusid/models/fee_type_request.py +3 -3
  152. lusid/models/fixed_leg.py +3 -3
  153. lusid/models/fixed_schedule.py +3 -3
  154. lusid/models/flexible_loan.py +3 -3
  155. lusid/models/float_schedule.py +4 -4
  156. lusid/models/floating_leg.py +3 -3
  157. lusid/models/flow_conventions.py +7 -1
  158. lusid/models/forward_rate_agreement.py +3 -3
  159. lusid/models/fund_configuration.py +44 -17
  160. lusid/models/fund_configuration_request.py +31 -19
  161. lusid/models/fund_id_list.py +99 -0
  162. lusid/models/fund_share_class.py +23 -8
  163. lusid/models/funding_leg.py +3 -3
  164. lusid/models/future.py +3 -3
  165. lusid/models/future_expiry_event.py +3 -3
  166. lusid/models/fx_forward.py +3 -3
  167. lusid/models/fx_forward_settlement_event.py +3 -3
  168. lusid/models/fx_option.py +3 -3
  169. lusid/models/fx_swap.py +3 -3
  170. lusid/models/group_reconciliation_aggregate_attribute_rule.py +2 -2
  171. lusid/models/group_reconciliation_aggregate_attribute_values.py +86 -0
  172. lusid/models/group_reconciliation_aggregate_comparison_rule_operand.py +1 -1
  173. lusid/models/group_reconciliation_comparison_result.py +148 -0
  174. lusid/models/group_reconciliation_core_attribute_values.py +86 -0
  175. lusid/models/group_reconciliation_core_comparison_rule_operand.py +1 -1
  176. lusid/models/group_reconciliation_date_pair.py +81 -0
  177. lusid/models/group_reconciliation_dates.py +78 -0
  178. lusid/models/group_reconciliation_definition.py +136 -0
  179. lusid/models/group_reconciliation_definition_comparison_ruleset_ids.py +83 -0
  180. lusid/models/group_reconciliation_definition_currencies.py +71 -0
  181. lusid/models/group_reconciliation_definition_portfolio_entity_ids.py +86 -0
  182. lusid/models/group_reconciliation_definition_recipe_ids.py +78 -0
  183. lusid/models/group_reconciliation_instance_id.py +71 -0
  184. lusid/models/group_reconciliation_result_statuses.py +89 -0
  185. lusid/models/group_reconciliation_result_types.py +96 -0
  186. lusid/models/group_reconciliation_review_statuses.py +96 -0
  187. lusid/models/group_reconciliation_run_details.py +76 -0
  188. lusid/models/group_reconciliation_run_request.py +75 -0
  189. lusid/models/{metadata_key_value_response.py → group_reconciliation_run_response.py} +20 -29
  190. lusid/models/group_reconciliation_summary.py +121 -0
  191. lusid/models/group_reconciliation_user_review.py +112 -0
  192. lusid/models/group_reconciliation_user_review_add.py +88 -0
  193. lusid/models/group_reconciliation_user_review_break_code.py +80 -0
  194. lusid/models/group_reconciliation_user_review_comment.py +80 -0
  195. lusid/models/group_reconciliation_user_review_match_key.py +80 -0
  196. lusid/models/group_reconciliation_user_review_remove.py +88 -0
  197. lusid/models/holding_contributor.py +11 -4
  198. lusid/models/holding_ids_request.py +69 -0
  199. lusid/models/inflation_leg.py +3 -3
  200. lusid/models/inflation_linked_bond.py +3 -3
  201. lusid/models/inflation_swap.py +3 -3
  202. lusid/models/informational_error_event.py +3 -3
  203. lusid/models/informational_event.py +3 -3
  204. lusid/models/instrument.py +7 -1
  205. lusid/models/instrument_definition.py +8 -2
  206. lusid/models/instrument_event.py +17 -5
  207. lusid/models/instrument_event_holder.py +9 -1
  208. lusid/models/instrument_event_type.py +12 -0
  209. lusid/models/instrument_leg.py +3 -3
  210. lusid/models/instrument_list.py +3 -3
  211. lusid/models/instrument_type.py +2 -0
  212. lusid/models/interest_rate_swap.py +3 -3
  213. lusid/models/interest_rate_swaption.py +3 -3
  214. lusid/models/intermediate_securities_distribution_event.py +140 -0
  215. lusid/models/lapse_election.py +73 -0
  216. lusid/models/loan_facility.py +97 -0
  217. lusid/models/lusid_instrument.py +7 -5
  218. lusid/models/market_data_key_rule.py +5 -3
  219. lusid/models/market_data_specific_rule.py +5 -3
  220. lusid/models/mastered_instrument.py +139 -0
  221. lusid/models/maturity_event.py +3 -3
  222. lusid/models/mbs_coupon_event.py +102 -0
  223. lusid/models/mbs_interest_deferral_event.py +102 -0
  224. lusid/models/mbs_interest_shortfall_event.py +102 -0
  225. lusid/models/mbs_principal_event.py +102 -0
  226. lusid/models/mbs_principal_write_off_event.py +102 -0
  227. lusid/models/merger_event.py +22 -22
  228. lusid/models/new_instrument.py +1 -1
  229. lusid/models/open_event.py +3 -3
  230. lusid/models/option_exercise_cash_event.py +144 -0
  231. lusid/models/option_exercise_election.py +73 -0
  232. lusid/models/option_exercise_physical_event.py +149 -0
  233. lusid/models/output_transaction.py +9 -2
  234. lusid/models/paged_resource_list_of_group_reconciliation_comparison_result.py +113 -0
  235. lusid/models/paged_resource_list_of_group_reconciliation_comparison_ruleset.py +113 -0
  236. lusid/models/paged_resource_list_of_group_reconciliation_definition.py +113 -0
  237. lusid/models/portfolio.py +3 -3
  238. lusid/models/portfolio_details.py +3 -3
  239. lusid/models/portfolio_group_id_list.py +3 -3
  240. lusid/models/portfolio_id_list.py +3 -3
  241. lusid/models/portfolio_without_href.py +3 -3
  242. lusid/models/pricing_options.py +8 -2
  243. lusid/models/property_list.py +3 -3
  244. lusid/models/protection_payout_cash_flow_event.py +102 -0
  245. lusid/models/raw_vendor_event.py +3 -3
  246. lusid/models/reference_instrument.py +3 -3
  247. lusid/models/reference_list.py +6 -5
  248. lusid/models/reference_list_type.py +1 -0
  249. lusid/models/repo.py +3 -3
  250. lusid/models/reset_event.py +3 -3
  251. lusid/models/resource_list_of_change_interval.py +113 -0
  252. lusid/models/resource_list_of_output_transaction.py +113 -0
  253. lusid/models/return_zero_pv_options.py +69 -0
  254. lusid/models/reverse_stock_split_event.py +21 -7
  255. lusid/models/scrip_dividend_event.py +3 -3
  256. lusid/models/settlement_cycle.py +79 -0
  257. lusid/models/share_class_dealing_breakdown.py +3 -2
  258. lusid/models/share_class_details.py +18 -1
  259. lusid/models/simple_cash_flow_loan.py +3 -3
  260. lusid/models/simple_instrument.py +3 -3
  261. lusid/models/simple_rounding_convention.py +76 -0
  262. lusid/models/spin_off_event.py +3 -3
  263. lusid/models/staged_modification_effective_range.py +2 -2
  264. lusid/models/stock_dividend_event.py +20 -6
  265. lusid/models/stock_split_event.py +3 -3
  266. lusid/models/string_list.py +3 -3
  267. lusid/models/swap_cash_flow_event.py +3 -3
  268. lusid/models/swap_principal_event.py +3 -3
  269. lusid/models/target_tax_lot.py +23 -2
  270. lusid/models/target_tax_lot_request.py +23 -2
  271. lusid/models/tender_event.py +172 -0
  272. lusid/models/term_deposit.py +3 -3
  273. lusid/models/total_return_swap.py +4 -4
  274. lusid/models/transaction.py +9 -2
  275. lusid/models/transaction_date_windows.py +85 -0
  276. lusid/models/transaction_price.py +3 -3
  277. lusid/models/transaction_price_type.py +2 -0
  278. lusid/models/transaction_request.py +9 -2
  279. lusid/models/transition_event.py +3 -3
  280. lusid/models/trigger_event.py +3 -3
  281. lusid/models/update_fee_type_request.py +4 -4
  282. lusid/models/update_group_reconciliation_comparison_ruleset_request.py +91 -0
  283. lusid/models/update_group_reconciliation_definition_request.py +107 -0
  284. lusid/models/update_reference_data_request.py +87 -0
  285. lusid/models/update_staging_rule_set_request.py +1 -6
  286. lusid/models/upsert_custom_entities_response.py +20 -1
  287. lusid/models/upsert_reference_portfolio_constituent_properties_request.py +84 -0
  288. lusid/models/upsert_reference_portfolio_constituent_properties_response.py +115 -0
  289. lusid/models/valuation_point_data_query_parameters.py +3 -3
  290. lusid/models/valuation_point_data_response.py +8 -13
  291. lusid/rest.py +70 -20
  292. {lusid_sdk-2.1.405.dist-info → lusid_sdk-2.1.537.dist-info}/METADATA +118 -26
  293. {lusid_sdk-2.1.405.dist-info → lusid_sdk-2.1.537.dist-info}/RECORD +294 -226
  294. {lusid_sdk-2.1.405.dist-info → lusid_sdk-2.1.537.dist-info}/WHEEL +0 -0
lusid/api_client.py CHANGED
@@ -155,7 +155,7 @@ class ApiClient:
155
155
  files=None, response_types_map=None, auth_settings=None,
156
156
  _return_http_data_only=None, collection_formats=None,
157
157
  _preload_content=True, _request_timeout=None, _host=None,
158
- _request_auth=None):
158
+ _request_auth=None, opts=None):
159
159
 
160
160
  config = self.configuration
161
161
 
@@ -223,7 +223,8 @@ class ApiClient:
223
223
  headers=header_params,
224
224
  post_params=post_params, body=body,
225
225
  _preload_content=_preload_content,
226
- _request_timeout=_request_timeout)
226
+ _request_timeout=_request_timeout,
227
+ opts=opts)
227
228
  except ApiException as e:
228
229
  if e.body:
229
230
  e.body = e.body.decode('utf-8')
@@ -372,7 +373,8 @@ class ApiClient:
372
373
  response_types_map=None, auth_settings=None,
373
374
  async_req=None, _return_http_data_only=None,
374
375
  collection_formats=None, _preload_content=True,
375
- _request_timeout=None, _host=None, _request_auth=None):
376
+ _request_timeout=None, _host=None, _request_auth=None,
377
+ opts=None):
376
378
  """Makes the HTTP request (synchronous) and returns deserialized data.
377
379
 
378
380
  To make an async_req request, set the async_req parameter.
@@ -399,10 +401,9 @@ class ApiClient:
399
401
  Default is True.
400
402
  :param collection_formats: dict of collection formats for path, query,
401
403
  header, and post parameters.
402
- :param _request_timeout: timeout setting for this request. If one
403
- number provided, it will be total request
404
- timeout. It can also be a pair (tuple) of
405
- (connection, read) timeouts.
404
+ :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
405
+ :param opts: Configuration options for this request
406
+ :type opts: ConfigurationOptions, optional
406
407
  :param _request_auth: set to override the auth_settings for an a single
407
408
  request; this effectively ignores the authentication
408
409
  in the spec for a single request.
@@ -421,7 +422,7 @@ class ApiClient:
421
422
  response_types_map, auth_settings,
422
423
  _return_http_data_only, collection_formats,
423
424
  _preload_content, _request_timeout, _host,
424
- _request_auth)
425
+ _request_auth, opts)
425
426
 
426
427
  return self.pool.apply_async(self.__call_api, (resource_path,
427
428
  method, path_params,
@@ -434,30 +435,34 @@ class ApiClient:
434
435
  collection_formats,
435
436
  _preload_content,
436
437
  _request_timeout,
437
- _host, _request_auth))
438
+ _host, _request_auth,
439
+ opts))
438
440
 
439
441
  def request(self, method, url, query_params=None, headers=None,
440
442
  post_params=None, body=None, _preload_content=True,
441
- _request_timeout=None):
443
+ _request_timeout=None, opts=None):
442
444
  """Makes the HTTP request using RESTClient."""
443
445
  if method == "GET":
444
446
  return self.rest_client.get_request(url,
445
447
  query_params=query_params,
446
448
  _preload_content=_preload_content,
447
449
  _request_timeout=_request_timeout,
448
- headers=headers)
450
+ headers=headers,
451
+ opts=opts)
449
452
  elif method == "HEAD":
450
453
  return self.rest_client.head_request(url,
451
454
  query_params=query_params,
452
455
  _preload_content=_preload_content,
453
456
  _request_timeout=_request_timeout,
454
- headers=headers)
457
+ headers=headers,
458
+ opts=opts)
455
459
  elif method == "OPTIONS":
456
460
  return self.rest_client.options_request(url,
457
461
  query_params=query_params,
458
462
  headers=headers,
459
463
  _preload_content=_preload_content,
460
- _request_timeout=_request_timeout)
464
+ _request_timeout=_request_timeout,
465
+ opts=opts)
461
466
  elif method == "POST":
462
467
  return self.rest_client.post_request(url,
463
468
  query_params=query_params,
@@ -465,7 +470,8 @@ class ApiClient:
465
470
  post_params=post_params,
466
471
  _preload_content=_preload_content,
467
472
  _request_timeout=_request_timeout,
468
- body=body)
473
+ body=body,
474
+ opts=opts)
469
475
  elif method == "PUT":
470
476
  return self.rest_client.put_request(url,
471
477
  query_params=query_params,
@@ -473,7 +479,8 @@ class ApiClient:
473
479
  post_params=post_params,
474
480
  _preload_content=_preload_content,
475
481
  _request_timeout=_request_timeout,
476
- body=body)
482
+ body=body,
483
+ opts=opts)
477
484
  elif method == "PATCH":
478
485
  return self.rest_client.patch_request(url,
479
486
  query_params=query_params,
@@ -481,14 +488,16 @@ class ApiClient:
481
488
  post_params=post_params,
482
489
  _preload_content=_preload_content,
483
490
  _request_timeout=_request_timeout,
484
- body=body)
491
+ body=body,
492
+ opts=opts)
485
493
  elif method == "DELETE":
486
494
  return self.rest_client.delete_request(url,
487
495
  query_params=query_params,
488
496
  headers=headers,
489
497
  _preload_content=_preload_content,
490
498
  _request_timeout=_request_timeout,
491
- body=body)
499
+ body=body,
500
+ opts=opts)
492
501
  else:
493
502
  raise ApiValueError(
494
503
  "http method must be `GET`, `HEAD`, `OPTIONS`,"
lusid/configuration.py CHANGED
@@ -26,6 +26,56 @@ JSON_SCHEMA_VALIDATION_KEYWORDS = {
26
26
  'minLength', 'pattern', 'maxItems', 'minItems'
27
27
  }
28
28
 
29
+ class Timeouts:
30
+
31
+ @property
32
+ def total_timeout_ms(self):
33
+ return self.__total_timeout_ms
34
+
35
+ @total_timeout_ms.setter
36
+ def total_timeout_ms(self, value):
37
+ if not isinstance(value, int):
38
+ raise TypeError(f"total_timeout_ms must be type int but type '{type(value)}' used")
39
+ if value < 0:
40
+ raise ValueError(f"total_timeout_ms must be an integer greater than or equal to zero")
41
+ self.__total_timeout_ms = value
42
+
43
+ @property
44
+ def connect_timeout_ms(self):
45
+ return self.__connect_timeout_ms
46
+
47
+ @connect_timeout_ms.setter
48
+ def connect_timeout_ms(self, value):
49
+ if not isinstance(value, int):
50
+ raise TypeError(f"connect_timeout_ms must be type int but type '{type(value)}' used")
51
+ if value < 0:
52
+ raise ValueError(f"connect_timeout_ms must be an integer greater than or equal to zero")
53
+ self.__connect_timeout_ms = value
54
+
55
+ @property
56
+ def read_timeout_ms(self):
57
+ return self.__read_timeout_ms
58
+
59
+ @read_timeout_ms.setter
60
+ def read_timeout_ms(self, value):
61
+ if not isinstance(value, int):
62
+ raise TypeError(f"read_timeout_ms must be type int but type '{type(value)}' used")
63
+ if value < 0:
64
+ raise ValueError(f"read_timeout_ms must be an integer greater than or equal to zero")
65
+ self.__read_timeout_ms = value
66
+
67
+ def __init__(self, total_timeout_ms: int, connect_timeout_ms: int, read_timeout_ms: int):
68
+ self.total_timeout_ms = total_timeout_ms
69
+ self.connect_timeout_ms = connect_timeout_ms
70
+ self.read_timeout_ms = read_timeout_ms
71
+
72
+ def get_default():
73
+ return Timeouts(
74
+ total_timeout_ms=Configuration.DEFAULT_TOTAL_TIMEOUT_MS,
75
+ connect_timeout_ms=Configuration.DEFAULT_CONNECT_TIMEOUT_MS,
76
+ read_timeout_ms=Configuration.DEFAULT_READ_TIMEOUT_MS
77
+ )
78
+
29
79
  class Configuration:
30
80
  """This class contains various settings of the API client.
31
81
 
@@ -55,6 +105,12 @@ class Configuration:
55
105
 
56
106
  :Example:
57
107
  """
108
+
109
+ DEFAULT_TOTAL_TIMEOUT_MS: int = 1800_000
110
+ DEFAULT_CONNECT_TIMEOUT_MS: int = 0
111
+ DEFAULT_READ_TIMEOUT_MS: int = 0
112
+ DEFAULT_RATE_LIMIT_RETRIES: int = 2
113
+ DEFAULT_RETRIES: int = 3
58
114
 
59
115
  _default = None
60
116
 
@@ -65,7 +121,11 @@ class Configuration:
65
121
  server_index=None, server_variables=None,
66
122
  server_operation_index=None, server_operation_variables=None,
67
123
  ssl_ca_cert=None,
68
- ) -> None:
124
+ timeouts=Timeouts(
125
+ total_timeout_ms=DEFAULT_TOTAL_TIMEOUT_MS,
126
+ connect_timeout_ms=DEFAULT_CONNECT_TIMEOUT_MS,
127
+ read_timeout_ms=DEFAULT_READ_TIMEOUT_MS),
128
+ rate_limit_retries=DEFAULT_RATE_LIMIT_RETRIES) -> None:
69
129
  """Constructor
70
130
  """
71
131
  self._base_path = "https://www.lusid.com/api" if host is None else host
@@ -179,6 +239,9 @@ class Configuration:
179
239
  self.date_format = "%Y-%m-%d"
180
240
  """date format
181
241
  """
242
+
243
+ self.timeouts = timeouts
244
+ self.rate_limit_retries = rate_limit_retries
182
245
 
183
246
  def __deepcopy__(self, memo):
184
247
  cls = self.__class__
@@ -382,7 +445,7 @@ class Configuration:
382
445
  return "Python SDK Debug Report:\n"\
383
446
  "OS: {env}\n"\
384
447
  "Python Version: {pyversion}\n"\
385
- "Version of the API: 0.11.6835\n"\
448
+ "Version of the API: 0.11.6966\n"\
386
449
  "SDK Package Version: {package_version}".\
387
450
  format(env=sys.platform, pyversion=sys.version, package_version=package_version)
388
451
 
@@ -447,3 +510,25 @@ class Configuration:
447
510
  """Fix base path."""
448
511
  self._base_path = value
449
512
  self.server_index = None
513
+
514
+ @property
515
+ def timeouts(self):
516
+ return self._timeouts
517
+
518
+ @timeouts.setter
519
+ def timeouts(self, value):
520
+ if not isinstance(value, Timeouts):
521
+ raise TypeError(f"timeouts must be type Timeouts but type '{type(value)}' used")
522
+ self._timeouts = value
523
+
524
+ @property
525
+ def rate_limit_retries(self):
526
+ return self._rate_limit_retries
527
+
528
+ @rate_limit_retries.setter
529
+ def rate_limit_retries(self, value):
530
+ if not isinstance(value, int):
531
+ raise TypeError(f"rate_limit_retries must be type int but type '{type(value)}' used")
532
+ if value < 0:
533
+ raise ValueError(f"rate_limit_retries must be greater than or equal to zero but was '{value}'")
534
+ self._rate_limit_retries = value
@@ -154,7 +154,7 @@ class SyncApiClient:
154
154
  files=None, response_types_map=None, auth_settings=None,
155
155
  _return_http_data_only=None, collection_formats=None,
156
156
  _preload_content=True, _request_timeout=None, _host=None,
157
- _request_auth=None):
157
+ _request_auth=None, opts=None):
158
158
 
159
159
  config = self.configuration
160
160
 
@@ -222,7 +222,8 @@ class SyncApiClient:
222
222
  headers=header_params,
223
223
  post_params=post_params, body=body,
224
224
  _preload_content=_preload_content,
225
- _request_timeout=_request_timeout)
225
+ _request_timeout=_request_timeout,
226
+ opts=opts)
226
227
  except ApiException as e:
227
228
  if e.body:
228
229
  e.body = e.body.decode('utf-8')
@@ -371,7 +372,8 @@ class SyncApiClient:
371
372
  response_types_map=None, auth_settings=None,
372
373
  async_req=None, _return_http_data_only=None,
373
374
  collection_formats=None, _preload_content=True,
374
- _request_timeout=None, _host=None, _request_auth=None):
375
+ _request_timeout=None, _host=None, _request_auth=None,
376
+ opts=None):
375
377
  """Makes the HTTP request (synchronous) and returns deserialized data.
376
378
 
377
379
  To make an async_req request, set the async_req parameter.
@@ -398,10 +400,9 @@ class SyncApiClient:
398
400
  Default is True.
399
401
  :param collection_formats: dict of collection formats for path, query,
400
402
  header, and post parameters.
401
- :param _request_timeout: timeout setting for this request. If one
402
- number provided, it will be total request
403
- timeout. It can also be a pair (tuple) of
404
- (connection, read) timeouts.
403
+ :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
404
+ :param opts: Configuration options for this request
405
+ :type opts: ConfigurationOptions, optional
405
406
  :param _request_auth: set to override the auth_settings for an a single
406
407
  request; this effectively ignores the authentication
407
408
  in the spec for a single request.
@@ -420,7 +421,7 @@ class SyncApiClient:
420
421
  response_types_map, auth_settings,
421
422
  _return_http_data_only, collection_formats,
422
423
  _preload_content, _request_timeout, _host,
423
- _request_auth)
424
+ _request_auth, opts)
424
425
 
425
426
  return self.pool.apply_async(self.__call_api, (resource_path,
426
427
  method, path_params,
@@ -433,30 +434,33 @@ class SyncApiClient:
433
434
  collection_formats,
434
435
  _preload_content,
435
436
  _request_timeout,
436
- _host, _request_auth))
437
+ _host, _request_auth, opts))
437
438
 
438
439
  def request(self, method, url, query_params=None, headers=None,
439
440
  post_params=None, body=None, _preload_content=True,
440
- _request_timeout=None):
441
+ _request_timeout=None, opts=None):
441
442
  """Makes the HTTP request using RESTClient."""
442
443
  if method == "GET":
443
444
  return self.rest_client.get_request(url,
444
445
  query_params=query_params,
445
446
  _preload_content=_preload_content,
446
447
  _request_timeout=_request_timeout,
447
- headers=headers)
448
+ headers=headers,
449
+ opts=opts)
448
450
  elif method == "HEAD":
449
451
  return self.rest_client.head_request(url,
450
452
  query_params=query_params,
451
453
  _preload_content=_preload_content,
452
454
  _request_timeout=_request_timeout,
453
- headers=headers)
455
+ headers=headers,
456
+ opts=opts)
454
457
  elif method == "OPTIONS":
455
458
  return self.rest_client.options_request(url,
456
459
  query_params=query_params,
457
460
  headers=headers,
458
461
  _preload_content=_preload_content,
459
- _request_timeout=_request_timeout)
462
+ _request_timeout=_request_timeout,
463
+ opts=opts)
460
464
  elif method == "POST":
461
465
  return self.rest_client.post_request(url,
462
466
  query_params=query_params,
@@ -464,7 +468,8 @@ class SyncApiClient:
464
468
  post_params=post_params,
465
469
  _preload_content=_preload_content,
466
470
  _request_timeout=_request_timeout,
467
- body=body)
471
+ body=body,
472
+ opts=opts)
468
473
  elif method == "PUT":
469
474
  return self.rest_client.put_request(url,
470
475
  query_params=query_params,
@@ -472,7 +477,8 @@ class SyncApiClient:
472
477
  post_params=post_params,
473
478
  _preload_content=_preload_content,
474
479
  _request_timeout=_request_timeout,
475
- body=body)
480
+ body=body,
481
+ opts=opts)
476
482
  elif method == "PATCH":
477
483
  return self.rest_client.patch_request(url,
478
484
  query_params=query_params,
@@ -480,14 +486,16 @@ class SyncApiClient:
480
486
  post_params=post_params,
481
487
  _preload_content=_preload_content,
482
488
  _request_timeout=_request_timeout,
483
- body=body)
489
+ body=body,
490
+ opts=opts)
484
491
  elif method == "DELETE":
485
492
  return self.rest_client.delete_request(url,
486
493
  query_params=query_params,
487
494
  headers=headers,
488
495
  _preload_content=_preload_content,
489
496
  _request_timeout=_request_timeout,
490
- body=body)
497
+ body=body,
498
+ opts=opts)
491
499
  else:
492
500
  raise ApiValueError(
493
501
  "http method must be `GET`, `HEAD`, `OPTIONS`,"
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
  from lusid.api_client import ApiClient
3
+ from lusid.extensions.configuration_options import ConfigurationOptions
3
4
  from lusid.extensions.retry import (
4
5
  RetryingRestWrapper,
5
6
  RetryingRestWrapperAsync
@@ -68,6 +69,7 @@ class SyncApiClientFactory:
68
69
  ] = keep_alive_socket_options(),
69
70
  correlation_id: Optional[str] = None,
70
71
  app_name: Optional[str] = None,
72
+ opts: Optional[ConfigurationOptions] = None,
71
73
  ):
72
74
  """Create an ApiClientFactory which can build
73
75
  api objects with a configured ApiClient object
@@ -96,7 +98,8 @@ class SyncApiClientFactory:
96
98
  api_client_config = api_config.build_api_client_config(
97
99
  tcp_keep_alive=tcp_keep_alive,
98
100
  socket_options=socket_options,
99
- id_provider_response_handler=id_provider_response_handler
101
+ id_provider_response_handler=id_provider_response_handler,
102
+ opts=opts
100
103
  )
101
104
  self.__api_client = SyncApiClient(
102
105
  configuration=api_client_config,
@@ -107,7 +110,9 @@ class SyncApiClientFactory:
107
110
  if tcp_keep_alive:
108
111
  rc.pool_manager.pool_classes_by_scheme = {"http": TCPKeepAliveHTTPConnectionPool, "https": TCPKeepAliveHTTPSConnectionPool}
109
112
 
110
- wrapped_rest_client = rest_client_wrapper(rc)
113
+ wrapped_rest_client = rest_client_wrapper(
114
+ rest_object=rc,
115
+ rate_limit_retries=api_client_config.rate_limit_retries)
111
116
  self.__api_client.rest_client = wrapped_rest_client
112
117
 
113
118
  set_additional_api_client_headers(
@@ -153,7 +158,8 @@ class ApiClientFactory:
153
158
  correlation_id: Optional[str] = None,
154
159
  app_name: Optional[str] = None,
155
160
  client_session: Optional[ClientSession] = None,
156
- trace_configs: Optional[List[TraceConfig]] = None
161
+ trace_configs: Optional[List[TraceConfig]] = None,
162
+ opts: Optional[ConfigurationOptions] = None,
157
163
  ):
158
164
  """Create an ApiClientFactory which can build api
159
165
  objects with a configured ApiClient object
@@ -189,7 +195,8 @@ class ApiClientFactory:
189
195
  api_client_config = api_config.build_api_client_config(
190
196
  tcp_keep_alive=tcp_keep_alive,
191
197
  socket_options=socket_options,
192
- id_provider_response_handler=id_provider_response_handler
198
+ id_provider_response_handler=id_provider_response_handler,
199
+ opts=opts
193
200
  )
194
201
  self.__api_client = ApiClient(
195
202
  configuration=api_client_config,
@@ -218,7 +225,9 @@ class ApiClientFactory:
218
225
  logger.exception("client_session must be an aiohttp.ClientSession"
219
226
  " object with an initialised TCP Connector")
220
227
  rest_client_wrapper = RetryingRestWrapperAsync
221
- wrapped_rest_client = rest_client_wrapper(rc)
228
+ wrapped_rest_client = rest_client_wrapper(
229
+ rest_object=rc,
230
+ rate_limit_retries=api_client_config.rate_limit_retries)
222
231
  self.__api_client.rest_client = wrapped_rest_client
223
232
  set_additional_api_client_headers(
224
233
  self.__api_client, app_name=app_name, correlation_id=correlation_id
@@ -1,7 +1,8 @@
1
1
  import re
2
2
  import logging
3
3
  from typing import Optional, Union, Tuple, Any, Callable
4
- from lusid.configuration import Configuration
4
+ from lusid.configuration import Configuration, Timeouts
5
+ from lusid.extensions.configuration_options import ConfigurationOptions
5
6
  from lusid.extensions.refreshing_token import RefreshingToken
6
7
  from lusid.extensions.socket_keep_alive import keep_alive_socket_options
7
8
  from lusid.extensions.proxy_config import ProxyConfig
@@ -22,6 +23,10 @@ class ApiConfiguration:
22
23
  certificate_filename=None,
23
24
  proxy_config:Optional[ProxyConfig]=None,
24
25
  access_token=None,
26
+ total_timeout_ms=None,
27
+ connect_timeout_ms=None,
28
+ read_timeout_ms=None,
29
+ rate_limit_retries=None,
25
30
  ):
26
31
  """
27
32
  The configuration required to access LUSID, read more at https://support.finbourne.com/getting-started-with-apis-sdks
@@ -46,6 +51,10 @@ class ApiConfiguration:
46
51
  self.__certificate_filename = certificate_filename
47
52
  self.__proxy_config = proxy_config
48
53
  self.__access_token = access_token
54
+ self.__total_timeout_ms = total_timeout_ms
55
+ self.__connect_timeout_ms = connect_timeout_ms
56
+ self.__read_timeout_ms = read_timeout_ms
57
+ self.__rate_limit_retries = rate_limit_retries
49
58
 
50
59
  @property
51
60
  def token_url(self):
@@ -181,6 +190,35 @@ class ApiConfiguration:
181
190
  )
182
191
  raise
183
192
 
193
+ @property
194
+ def total_timeout_ms(self):
195
+ return self.__total_timeout_ms
196
+
197
+ @total_timeout_ms.setter
198
+ def total_timeout_ms(self, value):
199
+ self.__total_timeout_ms = value
200
+
201
+ @property
202
+ def connect_timeout_ms(self):
203
+ return self.__connect_timeout_ms
204
+
205
+ @connect_timeout_ms.setter
206
+ def connect_timeout_ms(self, value):
207
+ self.__connect_timeout_ms = value
208
+
209
+ @property
210
+ def read_timeout_ms(self):
211
+ return self.__read_timeout_ms
212
+
213
+ @read_timeout_ms.setter
214
+ def read_timeout_ms(self, value):
215
+ self.__read_timeout_ms = value
216
+
217
+ @property
218
+ def rate_limit_retries(self):
219
+ return self.__rate_limit_retries
220
+
221
+
184
222
  def build_api_client_config(
185
223
  self,
186
224
  tcp_keep_alive: bool = True,
@@ -188,6 +226,7 @@ class ApiConfiguration:
188
226
  Union[Tuple[Any, Any, Any], Tuple[Any, Any, None, int]]
189
227
  ] = keep_alive_socket_options(),
190
228
  id_provider_response_handler: Optional[Callable[[Response], None]] = None,
229
+ opts: ConfigurationOptions = None,
191
230
  ) -> Configuration:
192
231
  """Builds lusid.Configuration for initialising an api client.
193
232
 
@@ -219,6 +258,16 @@ class ApiConfiguration:
219
258
  access_token=access_token,
220
259
  host=self.api_url,
221
260
  ssl_ca_cert=self.certificate_filename,
261
+ timeouts=Timeouts(
262
+ total_timeout_ms=opts.total_timeout_ms if opts and opts.total_timeout_ms != None else
263
+ self.total_timeout_ms if self.total_timeout_ms != None else Configuration.DEFAULT_TOTAL_TIMEOUT_MS,
264
+ connect_timeout_ms=opts.connect_timeout_ms if opts and opts.connect_timeout_ms != None else
265
+ self.connect_timeout_ms if self.connect_timeout_ms != None else Configuration.DEFAULT_CONNECT_TIMEOUT_MS,
266
+ read_timeout_ms=opts.read_timeout_ms if opts and opts.read_timeout_ms != None else
267
+ self.read_timeout_ms if self.read_timeout_ms != None else Configuration.DEFAULT_READ_TIMEOUT_MS
268
+ ),
269
+ rate_limit_retries=opts.rate_limit_retries if opts != None and opts.rate_limit_retries != None else
270
+ self.rate_limit_retries if self.rate_limit_retries != None else Configuration.DEFAULT_RATE_LIMIT_RETRIES
222
271
  )
223
272
  if tcp_keep_alive:
224
273
  config.socket_options = socket_options or keep_alive_socket_options()
@@ -5,6 +5,7 @@ import logging
5
5
  from lusid.extensions.proxy_config import ProxyConfig
6
6
  from lusid.extensions.api_configuration import ApiConfiguration
7
7
  from lusid.extensions.file_access_token import FileAccessToken
8
+ from lusid.extensions.configuration_options import ConfigurationOptions
8
9
 
9
10
  logger = logging.getLogger(__name__)
10
11
 
@@ -21,7 +22,11 @@ ENVIRONMENT_CONFIG_KEYS = {
21
22
  "proxy_address": "FBN_PROXY_ADDRESS",
22
23
  "proxy_username": "FBN_PROXY_USERNAME",
23
24
  "proxy_password": "FBN_PROXY_PASSWORD",
24
- "access_token": "FBN_ACCESS_TOKEN"
25
+ "access_token": "FBN_ACCESS_TOKEN",
26
+ "total_timeout_ms": "FBN_TOTAL_TIMEOUT_MS",
27
+ "connect_timeout_ms": "FBN_CONNECT_TIMEOUT_MS",
28
+ "read_timeout_ms": "FBN_READ_TIMEOUT_MS",
29
+ "rate_limit_retries": "FBN_RATE_LIMIT_RETRIES",
25
30
  }
26
31
 
27
32
  SECRETS_FILE_CONFIG_KEYS = {
@@ -37,7 +42,11 @@ SECRETS_FILE_CONFIG_KEYS = {
37
42
  "proxy_address": "address",
38
43
  "proxy_username": "username",
39
44
  "proxy_password": "password",
40
- "access_token": "accessToken"
45
+ "access_token": "accessToken",
46
+ "total_timeout_ms": "totalTimeoutMs",
47
+ "connect_timeout_ms": "connectTimeoutMs",
48
+ "read_timeout_ms": "readTimeoutMs",
49
+ "rate_limit_retries": "rateLimitRetries",
41
50
  }
42
51
 
43
52
 
@@ -47,7 +56,7 @@ class ConfigurationLoader(Protocol):
47
56
  environment variables with preference given to the secrets file.
48
57
  """
49
58
 
50
- def load_config(self) -> Dict[str, str]:
59
+ def load_config(self) -> Dict[str, object]:
51
60
  pass
52
61
 
53
62
 
@@ -67,12 +76,12 @@ class SecretsFileConfigurationLoader:
67
76
  """
68
77
  self._api_secrets_file = api_secrets_file or ""
69
78
 
70
- def load_config(self) -> Dict[str, str]:
79
+ def load_config(self) -> Dict[str, object]:
71
80
  """reads config from the provided secrets file
72
81
 
73
82
  Returns
74
83
  -------
75
- Dict[str, str]
84
+ Dict[str, object]
76
85
  dictionary that can be loaded into an ApiConfiguration object
77
86
  """
78
87
  # The secrets file is a nested dictionary, set the names of the top level keys
@@ -117,12 +126,12 @@ class SecretsFileConfigurationLoader:
117
126
  class EnvironmentVariablesConfigurationLoader:
118
127
  """ConfigurationLoader which reads config from environment variables
119
128
  """
120
- def load_config(self) -> Dict[str, str]:
129
+ def load_config(self) -> Dict[str, object]:
121
130
  """reads config from environment variables
122
131
 
123
132
  Returns
124
133
  -------
125
- Dict[str, str]
134
+ Dict[str, object]
126
135
  dictionary that can be loaded into an ApiConfiguration object
127
136
  """
128
137
  logger.debug("loading config from environment variables")
@@ -134,6 +143,13 @@ class EnvironmentVariablesConfigurationLoader:
134
143
  }
135
144
  if not populated_api_config_values["api_url"]:
136
145
  populated_api_config_values["api_url"] = populated_api_config_values["previous_api_url"]
146
+ # ensure that these values are ints
147
+ for key in ["total_timeout_ms", "connect_timeout_ms", "read_timeout_ms", "rate_limit_retries"]:
148
+ if populated_api_config_values[key]:
149
+ try:
150
+ populated_api_config_values[key] = int(populated_api_config_values[key])
151
+ except ValueError as e:
152
+ raise ValueError(f"invalid value for '{key}' - value must be an integer if set")
137
153
  del(populated_api_config_values["previous_api_url"])
138
154
  populated_proxy_values = {
139
155
  key: os.environ.get(value)
@@ -162,7 +178,11 @@ class ArgsConfigurationLoader:
162
178
  proxy_address:Optional[str]=None,
163
179
  proxy_username:Optional[str]=None,
164
180
  proxy_password:Optional[str]=None,
165
- access_token:Optional[str]=None
181
+ access_token:Optional[str]=None,
182
+ total_timeout_ms:Optional[int]=None,
183
+ connect_timeout_ms:Optional[int]=None,
184
+ read_timeout_ms:Optional[int]=None,
185
+ rate_limit_retries:Optional[int]=None,
166
186
  ):
167
187
  """kwargs passed to this constructor used to build ApiConfiguration
168
188
  """
@@ -178,13 +198,17 @@ class ArgsConfigurationLoader:
178
198
  self.__proxy_username = proxy_username
179
199
  self.__proxy_password = proxy_password
180
200
  self.__access_token = access_token
201
+ self.__total_timeout_ms = total_timeout_ms
202
+ self.__connect_timeout_ms = connect_timeout_ms
203
+ self.__read_timeout_ms = read_timeout_ms
204
+ self.__rate_limit_retries = rate_limit_retries
181
205
 
182
- def load_config(self) -> Dict[str, str]:
206
+ def load_config(self) -> Dict[str, object]:
183
207
  """load configuration from kwargs passed to constructor
184
208
 
185
209
  Returns
186
210
  -------
187
- Dict[str, str]
211
+ Dict[str, object]
188
212
  dictionary that can be loaded into an ApiConfiguration object
189
213
  """
190
214
  logger.debug("loading config from arguments passed to ArgsConfigurationLoader")
@@ -200,7 +224,11 @@ class ArgsConfigurationLoader:
200
224
  "proxy_address" : self.__proxy_address,
201
225
  "proxy_username" : self.__proxy_username,
202
226
  "proxy_password" : self.__proxy_password,
203
- "access_token" : self.__access_token
227
+ "access_token" : self.__access_token,
228
+ "total_timeout_ms" : self.__total_timeout_ms,
229
+ "connect_timeout_ms" : self.__connect_timeout_ms,
230
+ "read_timeout_ms" : self.__read_timeout_ms,
231
+ "rate_limit_retries" : self.__rate_limit_retries,
204
232
  }
205
233
 
206
234