orionapi 2.30.0__tar.gz → 2.30.2__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: orionapi
3
- Version: 2.30.0
3
+ Version: 2.30.2
4
4
  Summary: A python interface for the Orion Advisors platform web API
5
5
  Author: spencerogden-dsam
6
6
  Author-email: 67068943+spencerogden-dsam@users.noreply.github.com
@@ -1,4 +1,4 @@
1
- __version__ = "2.30.0"
1
+ __version__ = "2.30.2"
2
2
 
3
3
  import logging
4
4
  import re
@@ -4843,46 +4843,46 @@ class EclipseV1(EclipseBase):
4843
4843
  def set_portfolio_tradeable(self, portfolio_id, tradeable=True, sync=True):
4844
4844
  """Set whether trading is allowed for a portfolio.
4845
4845
 
4846
+ Uses the v2 ``setPortfolioTradeBlock`` action, which accepts only
4847
+ ``{"id", "doNotTrade"}`` and therefore cannot touch any other portfolio
4848
+ field. The older approach (GET the portfolio, rebuild the v1 PUT payload
4849
+ by hand) rejected portfolios with no primary team and risked stripping
4850
+ teams, trading instructions and auto-rebalance settings that the
4851
+ rebuilt payload did not carry. Verified live 2026-09-10 on portfolio
4852
+ 209: the flag flips and every ``general``/``teams`` field is unchanged.
4853
+
4846
4854
  Args:
4847
4855
  portfolio_id: Portfolio ID
4848
4856
  tradeable: True to allow trading, False to block (default True)
4849
4857
  sync: Wait for analytics to complete (default True)
4850
4858
 
4851
4859
  Returns:
4852
- dict: Updated portfolio details
4860
+ dict: Updated portfolio details (same shape as :meth:`get_portfolio`)
4853
4861
  """
4854
4862
  if not isinstance(portfolio_id, int) or portfolio_id < 1:
4855
4863
  raise ValueError("portfolio_id must be a positive integer")
4856
4864
  if not isinstance(tradeable, bool):
4857
4865
  raise ValueError("tradeable must be a boolean")
4858
4866
 
4859
- # Get current portfolio to preserve other fields
4860
- portfolio = self.get_portfolio(portfolio_id)
4861
- general = portfolio.get("general", {})
4862
-
4863
- # Build payload preserving existing fields
4864
- payload = {
4865
- "name": general.get("portfolioName"),
4866
- "modelId": general.get("modelId"),
4867
- "isSleevePortfolio": general.get("sleevePortfolio", False),
4868
- "doNotTrade": 0 if tradeable else 1,
4869
- "tags": general.get("tags", ""),
4870
- "teamIds": general.get("teamIds", []),
4871
- "primaryTeamId": general.get("primaryTeamId"),
4872
- }
4873
-
4874
- res = self.api_request(
4875
- f"{self.base_url}/portfolio/portfolios/{portfolio_id}",
4867
+ self.api_request(
4868
+ f"{self.base_url_v2}/Portfolio/Portfolios/action/setPortfolioTradeBlock",
4876
4869
  requests.put,
4877
- json=payload,
4870
+ json=[{"id": portfolio_id, "doNotTrade": not tradeable}],
4878
4871
  )
4879
- result = res.json()
4872
+ result = self.get_portfolio(portfolio_id)
4880
4873
  self._maybe_wait_for_analytics(sync)
4881
4874
  return result
4882
4875
 
4883
4876
  def set_account_tradeable(self, account_id, trade_restriction="tradeable", sync=True):
4884
4877
  """Set trading restrictions for an account.
4885
4878
 
4879
+ Uses the v2 ``setAccountTradeBlock`` action, which accepts only
4880
+ ``{"id", "isDoNotBuySell", "isCustodialRestriction"}`` and therefore
4881
+ cannot touch any other account field. The older approach rebuilt the
4882
+ v1 ``PUT /account/accounts/{id}`` payload from ``generalSection`` of the
4883
+ GET DTO, but the account DTO is flat (no ``generalSection``), so it was
4884
+ sending ``accountName: null`` / ``portfolioId: null`` alongside the flags.
4885
+
4886
4886
  Args:
4887
4887
  account_id: Internal Eclipse account ID
4888
4888
  trade_restriction: One of:
@@ -4892,7 +4892,8 @@ class EclipseV1(EclipseBase):
4892
4892
  sync: Wait for analytics to complete (default True)
4893
4893
 
4894
4894
  Returns:
4895
- dict: Updated account details
4895
+ dict: Updated account details (same shape as :meth:`get_account_details`;
4896
+ the flags are ``isDoNotBuySell`` and ``isCustodialRestriction``)
4896
4897
 
4897
4898
  Note:
4898
4899
  These are mutually exclusive options - only one can be active at a time.
@@ -4900,35 +4901,27 @@ class EclipseV1(EclipseBase):
4900
4901
  if not isinstance(account_id, int) or account_id < 1:
4901
4902
  raise ValueError("account_id must be a positive integer")
4902
4903
 
4903
- valid_restrictions = ["tradeable", "block_advisor", "block_custodian"]
4904
- if trade_restriction not in valid_restrictions:
4905
- raise ValueError(f"trade_restriction must be one of {valid_restrictions}")
4906
-
4907
- # Get current account details
4908
- account = self.get_account_details(account_id)
4909
- general = account.get("generalSection", {})
4910
-
4911
- # Build payload
4912
- payload = {
4913
- "accountName": general.get("accountName"),
4914
- "portfolioId": general.get("portfolioId"),
4904
+ flags = {
4905
+ "tradeable": (False, False),
4906
+ "block_advisor": (True, False),
4907
+ "block_custodian": (False, True),
4915
4908
  }
4909
+ if trade_restriction not in flags:
4910
+ raise ValueError(f"trade_restriction must be one of {list(flags)}")
4911
+ do_not_buy_sell, custodial_restriction = flags[trade_restriction]
4916
4912
 
4917
- # Set flags based on restriction type
4918
- if trade_restriction == "tradeable":
4919
- payload["doNotTrade"] = 0
4920
- payload["doNotTradeCustodian"] = 0
4921
- elif trade_restriction == "block_advisor":
4922
- payload["doNotTrade"] = 1
4923
- payload["doNotTradeCustodian"] = 0
4924
- elif trade_restriction == "block_custodian":
4925
- payload["doNotTrade"] = 0
4926
- payload["doNotTradeCustodian"] = 1
4927
-
4928
- res = self.api_request(
4929
- f"{self.base_url}/account/accounts/{account_id}", requests.put, json=payload
4913
+ self.api_request(
4914
+ f"{self.base_url_v2}/Account/Accounts/action/setAccountTradeBlock",
4915
+ requests.put,
4916
+ json=[
4917
+ {
4918
+ "id": account_id,
4919
+ "isDoNotBuySell": do_not_buy_sell,
4920
+ "isCustodialRestriction": custodial_restriction,
4921
+ }
4922
+ ],
4930
4923
  )
4931
- result = res.json()
4924
+ result = self.get_account_details(account_id)
4932
4925
  self._maybe_wait_for_analytics(sync)
4933
4926
  return result
4934
4927
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "orionapi"
3
- version = "2.30.0"
3
+ version = "2.30.2"
4
4
  description = "A python interface for the Orion Advisors platform web API"
5
5
  authors = ["spencerogden-dsam <67068943+spencerogden-dsam@users.noreply.github.com>"]
6
6
 
File without changes