Source code for serenity_sdk.api.portfolio

import json
from typing import List, Optional
from uuid import UUID

from pydantic import parse_obj_as
from serenity_sdk.api.core import SerenityApi
from serenity_sdk.client.raw import CallType, SerenityClient
from serenity_sdk.types.common import Portfolio
from serenity_sdk.types.core import PortfolioAccountBalanceRequest
from serenity_types.portfolio.core import (
    PortfolioMetadata,
    PortfolioMetadataCreateRequest,
    PortfolioMetadataUpdateRequest,
    PortfolioSnapshot,
    PortfolioSnapshotCreateRequest,
    PortfolioSnapshotUpdateRequest,
)
from serenity_types.ledger.balance import Balance


[docs] class PortfolioApi(SerenityApi): def __init__(self, client: SerenityClient): """ :param client: the raw client to delegate to when making API calls """ super().__init__(client, "org/portfolios")
[docs] def create_portfolio_metadata( self, request: PortfolioMetadataCreateRequest ) -> PortfolioMetadata: """ Creates a new Portfolio Metadata. :param request: the request with the necessary details to create a new `PortfolioMetadata` :return: the created `PortfolioMetadata` """ req_json = json.loads(request.json()) raw_json = self._call_api("/metadata", {}, req_json, CallType.POST) return PortfolioMetadata.parse_obj(raw_json["result"])
[docs] def list_portfolio_metadata( self, offset: Optional[int] = 0, limit: Optional[int] = 1000 ) -> List[PortfolioMetadata]: """ List all `PortfolioMetadata` not marked as deleted. :param offset: the number of records to skip in the page. :param limit: the maximum number of items that should be returned. :return: a list `PortfolioMetadata` """ params = {"offset": str(offset), "limit": str(limit)} raw_json = self._call_api("/metadata", params, None, CallType.GET) return parse_obj_as(List[PortfolioMetadata], raw_json["result"])
[docs] def get_portfolio_metadata(self, metadata_id: UUID) -> PortfolioMetadata: """ Get the Portfolio Metadata. :param metadata_id: the PortfolioMetadata's unique identity :return: `PortfolioMetadata` """ raw_json = self._call_api(f"/metadata/{metadata_id}", {}, None, CallType.GET) return PortfolioMetadata.parse_obj(raw_json["result"])
[docs] def update_portfolio_metadata( self, metadata_id: UUID, request: PortfolioMetadataUpdateRequest ) -> PortfolioMetadata: """ Creates a copy of the Portfolio Metadata and increases the version by 1. :param request: the request with all the details needed to update the `PortfolioMetadata` :return: the updated `PortfolioMetadata` """ req_json = json.loads(request.json()) raw_json = self._call_api( f"/metadata/{metadata_id}", {}, req_json, CallType.PUT ) return PortfolioMetadata.parse_obj(raw_json["result"])
[docs] def delete_portfolio_metadata(self, metadata_id: UUID): """ Marks the Portfolio Metadata as deleted. :param metadata_id: the `PortfolioMetadata` to delete """ self._call_api(f"/metadata/{metadata_id}", {}, None, CallType.DELETE)
[docs] def get_balances_by_metadata_id( self, request: PortfolioAccountBalanceRequest ) -> List[Balance]: """ Get Balances by account_ids in Portfolio Metadata :param request: the request with the `metadata_id` :return: a list of `Balance` """ metadata_id = request.metadata_id req_json = json.loads(request.json()) raw_json = self._call_api( f"/metadata/{metadata_id}/balances", {}, req_json, CallType.GET ) return parse_obj_as(List[Balance], raw_json["result"])
[docs] def create_portfolio_snapshot( self, request: PortfolioSnapshotCreateRequest ) -> PortfolioSnapshot: """ Creates a Portfolio Snapshot. :param request: the request with the necessary details to create a new `PortfolioSnapshot` :return: the created `PortfolioSnapshot` """ req_json = json.loads(request.json()) raw_json = self._call_api("/snapshots", {}, req_json, CallType.POST) return PortfolioSnapshot.parse_obj(raw_json["result"])
[docs] def update_portfolio_snapshot( self, snapshot_id: UUID, request: PortfolioSnapshotUpdateRequest ) -> PortfolioSnapshot: """ Creates a copy of the Portfolio Snapshot and increases the version by 1. :param request: the request with the necessary details to update an `PortfolioSnapshot` :return: the updated `PortfolioSnapshot` """ req_json = json.loads(request.json()) raw_json = self._call_api( f"/snapshots/{snapshot_id}", {}, req_json, CallType.PUT ) return PortfolioSnapshot.parse_obj(raw_json["result"])
[docs] def delete_portfolio_snapshot(self, snapshot_id: UUID) -> bool: """ Mark the Portfolio Snapshot as deleted. :param snapshot_id: the `PortfolioSnapshot` to delete """ self._call_api(f"/snapshots/{snapshot_id}", {}, None, CallType.DELETE) return True
[docs] def list_portfolio_snapshots( self, metadata_id: UUID, offset: Optional[int] = 0, limit: Optional[int] = 1000 ) -> List[PortfolioSnapshot]: """ List all `PortfolioSnapshot` entries that are associated with the given `metadata_id` :param metadata_id: the `PortfolioMetadata` id to retrieve the snapshots from. :param offset: the number of records to skip in the page. :param limit: the maximum number of items that should be returned. :return: a list `PortfolioSnapshot` """ params = {"offset": str(offset), "limit": str(limit)} raw_json = self._call_api( f"/metadata/{metadata_id}/snapshots", params, None, CallType.GET ) return parse_obj_as(List[PortfolioSnapshot], raw_json["result"])
[docs] def get_portfolio_snapshot(self, snapshot_id: UUID) -> PortfolioSnapshot: """ Get the Portfolio Snapshot. :param snapshot_id: the PortfolioSnapshot's unique identity :return: `PortfolioSnapshot` """ raw_json = self._call_api(f"/snapshots/{snapshot_id}", {}, None, CallType.GET) return PortfolioSnapshot.parse_obj(raw_json["result"])
[docs] def to_legacy_portfolio(self, portfolio_snapshot: PortfolioSnapshot) -> Portfolio: """ Convert the `PortfolioSnapshot` to a `Portfolio` type that's compatible with the current SDK Api. :param portfolio_snapshot: The `PortfolioSnapshot` to convert :return: `Portfolio` """ return Portfolio( assets={ balance.asset_id: balance.quantity for balance in portfolio_snapshot.balances } )