orionapi 2.29.0__tar.gz → 2.30.0__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.29.0
3
+ Version: 2.30.0
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.29.0"
1
+ __version__ = "2.30.0"
2
2
 
3
3
  import logging
4
4
  import re
@@ -2810,6 +2810,11 @@ class EclipseV1(EclipseBase):
2810
2810
  """Get portfolio details by ID.
2811
2811
 
2812
2812
  Returns dict with 'general', 'teams', 'issues', 'summary' sections.
2813
+ The 'general' section carries ``teamIds`` / ``primaryTeamId``. The
2814
+ 'teams' section's per-record field spelling is unspecified upstream
2815
+ (``id`` vs ``teamId``, ``name`` vs ``teamName``) — accept both, or use
2816
+ :meth:`get_portfolio_teams` for a normalized ``{id, name, is_primary}``
2817
+ view.
2813
2818
  """
2814
2819
  res = self.api_request(f"{self.base_url}/portfolio/portfolios/{portfolio_id}")
2815
2820
  return res.json()
@@ -6663,6 +6668,108 @@ class EclipseV1(EclipseBase):
6663
6668
  json=payload,
6664
6669
  ).json()
6665
6670
 
6671
+ # --- Admin: Teams (v1 reads) ---
6672
+ # The v1 team routes are the reliable team read on tenants where teams were
6673
+ # not created with an externalId — EclipseV2.get_teams returns [] there
6674
+ # (see its docstring). teamIds/primaryTeamId are required on the portfolio
6675
+ # record, so these are the reads that unblock create_portfolio.
6676
+
6677
+ def get_teams(self, is_active=None):
6678
+ """Get all teams (``GET /admin/teams``).
6679
+
6680
+ Args:
6681
+ is_active: When set, passed as ``isActive`` (e.g. ``True`` returns
6682
+ active teams only). When None (default), the parameter is
6683
+ omitted and all teams are returned.
6684
+
6685
+ Returns:
6686
+ list: Team dicts. At minimum ``{id, name}``; the full record also
6687
+ carries ``portfolioAccess``, ``modelAccess``, ``status``,
6688
+ ``numberOfUsers``, ``numberOfModels``, ``numberOfPortfolios``,
6689
+ ``numberOfAdvisors``, ``isDeleted``, ``createdOn/By``,
6690
+ ``editedOn/By``.
6691
+ """
6692
+ params = {}
6693
+ if is_active is not None:
6694
+ params["isActive"] = str(bool(is_active)).lower()
6695
+ res = self.api_request(f"{self.base_url}/admin/teams", params=params)
6696
+ return res.json()
6697
+
6698
+ def get_team(self, team_id):
6699
+ """Get details for a single team (``GET /admin/teams/{id}``).
6700
+
6701
+ Args:
6702
+ team_id: Eclipse team ID
6703
+
6704
+ Returns:
6705
+ dict: Team detail record
6706
+ """
6707
+ res = self.api_request(f"{self.base_url}/admin/teams/{team_id}")
6708
+ return res.json()
6709
+
6710
+ def get_team_portfolios(self, team_id):
6711
+ """Get portfolios associated with a team (``GET /admin/teams/{id}/portfolios``).
6712
+
6713
+ Args:
6714
+ team_id: Eclipse team ID
6715
+
6716
+ Returns:
6717
+ list: Portfolio dicts (``{id, name, isDeleted, createdOn/By, editedOn/By}``)
6718
+ """
6719
+ res = self.api_request(f"{self.base_url}/admin/teams/{team_id}/portfolios")
6720
+ return res.json()
6721
+
6722
+ def get_team_primary_portfolios(self, team_id):
6723
+ """Get portfolios where the team is set as primary
6724
+ (``GET /admin/teams/{id}/primaryPortfolios``).
6725
+
6726
+ Args:
6727
+ team_id: Eclipse team ID
6728
+
6729
+ Returns:
6730
+ list: Portfolio dicts (``{id, name, createdOn/By, editedOn/By}``)
6731
+ """
6732
+ res = self.api_request(f"{self.base_url}/admin/teams/{team_id}/primaryPortfolios")
6733
+ return res.json()
6734
+
6735
+ def get_portfolio_teams(self, portfolio_id):
6736
+ """Get the teams stamped on a portfolio, normalized.
6737
+
6738
+ Reads the ``teams`` section of ``GET /portfolio/portfolios/{id}``
6739
+ (see :meth:`get_portfolio`) and normalizes each record to
6740
+ ``{id, name, is_primary}``. Unlike the ``/admin/teams`` routes, this
6741
+ works for a credential that is on no team at all, so it is the team
6742
+ read of last resort for service accounts.
6743
+
6744
+ The upstream field spelling is unspecified (``id`` vs ``teamId``,
6745
+ ``name`` vs ``teamName``), so both are accepted. ``is_primary`` is
6746
+ derived from ``general.primaryTeamId`` when present, falling back to
6747
+ the record's own ``isPrimaryTeam`` flag.
6748
+
6749
+ Args:
6750
+ portfolio_id: Portfolio ID
6751
+
6752
+ Returns:
6753
+ list: ``{id, name, is_primary}`` dicts, one per team on the portfolio
6754
+ """
6755
+ portfolio = self.get_portfolio(portfolio_id)
6756
+ primary_team_id = portfolio.get("general", {}).get("primaryTeamId")
6757
+ normalized = []
6758
+ for team in portfolio.get("teams") or []:
6759
+ team_id = team.get("id", team.get("teamId"))
6760
+ if primary_team_id is not None:
6761
+ is_primary = team_id == primary_team_id
6762
+ else:
6763
+ is_primary = bool(team.get("isPrimaryTeam"))
6764
+ normalized.append(
6765
+ {
6766
+ "id": team_id,
6767
+ "name": team.get("name", team.get("teamName")),
6768
+ "is_primary": is_primary,
6769
+ }
6770
+ )
6771
+ return normalized
6772
+
6666
6773
  # --- Admin token (v1) ---
6667
6774
 
6668
6775
  def get_firm_token(self, payload):
@@ -10107,13 +10214,19 @@ class EclipseV2(EclipseBase):
10107
10214
  # --- Team / ServiceTeams / User ---
10108
10215
 
10109
10216
  def get_teams(self, external_id=None):
10110
- """Get teams.
10217
+ """Get teams (v2 ``Team/Team/GetTeams``).
10218
+
10219
+ Warning:
10220
+ Returns ``[]`` (HTTP 200) on tenants where teams were not created
10221
+ with an ``externalId`` — live-verified 2026-08-17. Prefer the v1
10222
+ route (:meth:`EclipseV1.get_teams`, ``GET /admin/teams``), which
10223
+ the :class:`Eclipse` unifier resolves to.
10111
10224
 
10112
10225
  Args:
10113
10226
  external_id: Optional external ID filter (maps to ``externalId``)
10114
10227
 
10115
10228
  Returns:
10116
- list: Team dicts
10229
+ list: Team dicts (``{teamId, teamName, isPrimaryTeam, ...}``)
10117
10230
  """
10118
10231
  params = {}
10119
10232
  if external_id is not None:
@@ -11713,6 +11826,21 @@ class Eclipse(EclipseBase):
11713
11826
  internal_account_id=internal_account_id,
11714
11827
  )
11715
11828
 
11829
+ # --- v1-preferred overrides (documented best-of-both choices) ----------------
11830
+
11831
+ def get_teams(self, is_active=None):
11832
+ """Teams via the v1 route (best: v2 ``GetTeams`` is empty on some tenants).
11833
+
11834
+ Delegates to :meth:`EclipseV1.get_teams` (``GET /admin/teams``),
11835
+ returning ``{id, name, ...}`` records. **Behavior change in 2.30.0:**
11836
+ this name previously resolved to :meth:`EclipseV2.get_teams`, which
11837
+ returns ``[]`` (with differently spelled ``{teamId, teamName,
11838
+ isPrimaryTeam}`` records) on tenants where teams were not created with
11839
+ an ``externalId``. Use ``self.v2.get_teams(external_id=...)`` for the
11840
+ v2 surface explicitly.
11841
+ """
11842
+ return self.v1.get_teams(is_active=is_active)
11843
+
11716
11844
 
11717
11845
  class EclipseAPI(Eclipse):
11718
11846
  """Deprecated alias of :class:`Eclipse` (best-of-both client).
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "orionapi"
3
- version = "2.29.0"
3
+ version = "2.30.0"
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