# coding: utf-8

"""
    LUSID API

    FINBOURNE Technology  # noqa: E501

    Contact: info@finbourne.com
    Generated by OpenAPI Generator (https://openapi-generator.tech)

    Do not edit the class manually.
"""


import re  # noqa: F401
import io
import warnings

from pydantic.v1 import validate_arguments, ValidationError
from typing import overload, Optional, Union, Awaitable

from datetime import datetime
from pydantic.v1 import Field, StrictBool, StrictInt, StrictStr
from typing import Dict, List, Optional
from typing_extensions import Annotated
from lusid.models.access_metadata_operation import AccessMetadataOperation
from lusid.models.access_metadata_value import AccessMetadataValue
from lusid.models.create_portfolio_group_request import CreatePortfolioGroupRequest
from lusid.models.deleted_entity_response import DeletedEntityResponse
from lusid.models.expanded_group import ExpandedGroup
from lusid.models.model_property import ModelProperty
from lusid.models.paged_resource_list_of_portfolio_group import PagedResourceListOfPortfolioGroup
from lusid.models.portfolio_group import PortfolioGroup
from lusid.models.portfolio_group_properties import PortfolioGroupProperties
from lusid.models.resource_id import ResourceId
from lusid.models.resource_list_of_access_metadata_value_of import ResourceListOfAccessMetadataValueOf
from lusid.models.resource_list_of_processed_command import ResourceListOfProcessedCommand
from lusid.models.resource_list_of_property_interval import ResourceListOfPropertyInterval
from lusid.models.resource_list_of_relation import ResourceListOfRelation
from lusid.models.resource_list_of_relationship import ResourceListOfRelationship
from lusid.models.transaction_query_parameters import TransactionQueryParameters
from lusid.models.update_portfolio_group_request import UpdatePortfolioGroupRequest
from lusid.models.upsert_portfolio_group_access_metadata_request import UpsertPortfolioGroupAccessMetadataRequest
from lusid.models.versioned_resource_list_of_a2_b_data_record import VersionedResourceListOfA2BDataRecord
from lusid.models.versioned_resource_list_of_output_transaction import VersionedResourceListOfOutputTransaction
from lusid.models.versioned_resource_list_of_portfolio_holding import VersionedResourceListOfPortfolioHolding
from lusid.models.versioned_resource_list_of_transaction import VersionedResourceListOfTransaction

from lusid.api_client import ApiClient
from lusid.api_response import ApiResponse
from lusid.exceptions import (  # noqa: F401
    ApiTypeError,
    ApiValueError
)
from lusid.extensions.configuration_options import ConfigurationOptions

# ensure templated type usages are imported
from pydantic.v1 import Field, StrictStr
from typing import Optional
from typing_extensions import Annotated

class PortfolioGroupsApi:
    """NOTE: This class is auto generated by OpenAPI Generator
    Ref: https://openapi-generator.tech

    Do not edit the class manually.
    """

    def __init__(self, api_client=None) -> None:
        if api_client is None:
            api_client = ApiClient.get_default()
        self.api_client = api_client


    @overload
    async def add_portfolio_to_group(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group to add a portfolio to.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group to add a portfolio to. Together with the scope this uniquely identifies the portfolio group.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label from which the portfolio will be added to the group.")] = None, resource_id : Annotated[Optional[ResourceId], Field(description="The resource identifier of the portfolio to add to the portfolio group.")] = None, **kwargs) -> PortfolioGroup:  # noqa: E501
        ...

    @overload
    def add_portfolio_to_group(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group to add a portfolio to.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group to add a portfolio to. Together with the scope this uniquely identifies the portfolio group.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label from which the portfolio will be added to the group.")] = None, resource_id : Annotated[Optional[ResourceId], Field(description="The resource identifier of the portfolio to add to the portfolio group.")] = None, async_req: Optional[bool]=True, **kwargs) -> PortfolioGroup:  # noqa: E501
        ...

    @validate_arguments
    def add_portfolio_to_group(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group to add a portfolio to.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group to add a portfolio to. Together with the scope this uniquely identifies the portfolio group.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label from which the portfolio will be added to the group.")] = None, resource_id : Annotated[Optional[ResourceId], Field(description="The resource identifier of the portfolio to add to the portfolio group.")] = None, async_req: Optional[bool]=None, **kwargs) -> Union[PortfolioGroup, Awaitable[PortfolioGroup]]:  # noqa: E501
        """[EARLY ACCESS] AddPortfolioToGroup: Add portfolio to group  # noqa: E501

        Add a single portfolio to a portfolio group.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.add_portfolio_to_group(scope, code, effective_at, resource_id, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the portfolio group to add a portfolio to. (required)
        :type scope: str
        :param code: The code of the portfolio group to add a portfolio to. Together with the scope this uniquely identifies the portfolio group. (required)
        :type code: str
        :param effective_at: The effective datetime or cut label from which the portfolio will be added to the group.
        :type effective_at: str
        :param resource_id: The resource identifier of the portfolio to add to the portfolio group.
        :type resource_id: ResourceId
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: PortfolioGroup
        """
        kwargs['_return_http_data_only'] = True
        if '_preload_content' in kwargs:
            message = "Error! Please call the add_portfolio_to_group_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data"  # noqa: E501
            raise ValueError(message)
        if async_req is not None:
            kwargs['async_req'] = async_req
        return self.add_portfolio_to_group_with_http_info(scope, code, effective_at, resource_id, **kwargs)  # noqa: E501

    @validate_arguments
    def add_portfolio_to_group_with_http_info(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group to add a portfolio to.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group to add a portfolio to. Together with the scope this uniquely identifies the portfolio group.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label from which the portfolio will be added to the group.")] = None, resource_id : Annotated[Optional[ResourceId], Field(description="The resource identifier of the portfolio to add to the portfolio group.")] = None, **kwargs) -> ApiResponse:  # noqa: E501
        """[EARLY ACCESS] AddPortfolioToGroup: Add portfolio to group  # noqa: E501

        Add a single portfolio to a portfolio group.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.add_portfolio_to_group_with_http_info(scope, code, effective_at, resource_id, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the portfolio group to add a portfolio to. (required)
        :type scope: str
        :param code: The code of the portfolio group to add a portfolio to. Together with the scope this uniquely identifies the portfolio group. (required)
        :type code: str
        :param effective_at: The effective datetime or cut label from which the portfolio will be added to the group.
        :type effective_at: str
        :param resource_id: The resource identifier of the portfolio to add to the portfolio group.
        :type resource_id: ResourceId
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _preload_content: if False, the ApiResponse.data will
                                 be set to none and raw_data will store the
                                 HTTP response body without reading/decoding.
                                 Default is True.
        :type _preload_content: bool, optional
        :param _return_http_data_only: response data instead of ApiResponse
                                       object with status code, headers, etc
        :type _return_http_data_only: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the authentication
                              in the spec for a single request.
        :type _request_auth: dict, optional
        :type _content_type: string, optional: force content-type for the request
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: tuple(PortfolioGroup, status_code(int), headers(HTTPHeaderDict))
        """

        _params = locals()

        _all_params = [
            'scope',
            'code',
            'effective_at',
            'resource_id'
        ]
        _all_params.extend(
            [
                'async_req',
                '_return_http_data_only',
                '_preload_content',
                '_request_timeout',
                '_request_auth',
                '_content_type',
                '_headers',
                'opts'
            ]
        )

        # validate the arguments
        for _key, _val in _params['kwargs'].items():
            if _key not in _all_params:
                raise ApiTypeError(
                    "Got an unexpected keyword argument '%s'"
                    " to method add_portfolio_to_group" % _key
                )
            _params[_key] = _val
        del _params['kwargs']

        _collection_formats = {}

        # process the path parameters
        _path_params = {}
        if _params['scope']:
            _path_params['scope'] = _params['scope']

        if _params['code']:
            _path_params['code'] = _params['code']


        # process the query parameters
        _query_params = []
        if _params.get('effective_at') is not None:  # noqa: E501
            _query_params.append(('effectiveAt', _params['effective_at']))

        # process the header parameters
        _header_params = dict(_params.get('_headers', {}))
        # process the form parameters
        _form_params = []
        _files = {}
        # process the body parameter
        _body_params = None
        if _params['resource_id'] is not None:
            _body_params = _params['resource_id']

        # set the HTTP header `Accept`
        _header_params['Accept'] = self.api_client.select_header_accept(
            ['text/plain', 'application/json', 'text/json'])  # noqa: E501

        # set the HTTP header `Content-Type`
        _content_types_list = _params.get('_content_type',
            self.api_client.select_header_content_type(
                ['application/json-patch+json', 'application/json', 'text/json', 'application/*+json']))
        if _content_types_list:
                _header_params['Content-Type'] = _content_types_list

        # authentication setting
        _auth_settings = ['oauth2']  # noqa: E501

        _response_types_map = {
            '201': "PortfolioGroup",
            '400': "LusidValidationProblemDetails",
        }

        return self.api_client.call_api(
            '/api/portfoliogroups/{scope}/{code}/portfolios', 'POST',
            _path_params,
            _query_params,
            _header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            response_types_map=_response_types_map,
            auth_settings=_auth_settings,
            async_req=_params.get('async_req'),
            _return_http_data_only=_params.get('_return_http_data_only'),  # noqa: E501
            _preload_content=_params.get('_preload_content', True),
            _request_timeout=_params.get('_request_timeout'),
            opts=_params.get('opts'),
            collection_formats=_collection_formats,
            _request_auth=_params.get('_request_auth'))


    @overload
    async def add_sub_group_to_group(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group to add a portfolio group to.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group to add a portfolio group to. Together with the scope this uniquely identifies the portfolio group.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label from which the sub group will be added to the group.")] = None, resource_id : Annotated[Optional[ResourceId], Field(description="The resource identifier of the portfolio group to add to the portfolio group as a sub group.")] = None, **kwargs) -> PortfolioGroup:  # noqa: E501
        ...

    @overload
    def add_sub_group_to_group(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group to add a portfolio group to.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group to add a portfolio group to. Together with the scope this uniquely identifies the portfolio group.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label from which the sub group will be added to the group.")] = None, resource_id : Annotated[Optional[ResourceId], Field(description="The resource identifier of the portfolio group to add to the portfolio group as a sub group.")] = None, async_req: Optional[bool]=True, **kwargs) -> PortfolioGroup:  # noqa: E501
        ...

    @validate_arguments
    def add_sub_group_to_group(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group to add a portfolio group to.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group to add a portfolio group to. Together with the scope this uniquely identifies the portfolio group.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label from which the sub group will be added to the group.")] = None, resource_id : Annotated[Optional[ResourceId], Field(description="The resource identifier of the portfolio group to add to the portfolio group as a sub group.")] = None, async_req: Optional[bool]=None, **kwargs) -> Union[PortfolioGroup, Awaitable[PortfolioGroup]]:  # noqa: E501
        """[EARLY ACCESS] AddSubGroupToGroup: Add sub group to group  # noqa: E501

        Add a portfolio group to a portfolio group as a sub group.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.add_sub_group_to_group(scope, code, effective_at, resource_id, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the portfolio group to add a portfolio group to. (required)
        :type scope: str
        :param code: The code of the portfolio group to add a portfolio group to. Together with the scope this uniquely identifies the portfolio group. (required)
        :type code: str
        :param effective_at: The effective datetime or cut label from which the sub group will be added to the group.
        :type effective_at: str
        :param resource_id: The resource identifier of the portfolio group to add to the portfolio group as a sub group.
        :type resource_id: ResourceId
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: PortfolioGroup
        """
        kwargs['_return_http_data_only'] = True
        if '_preload_content' in kwargs:
            message = "Error! Please call the add_sub_group_to_group_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data"  # noqa: E501
            raise ValueError(message)
        if async_req is not None:
            kwargs['async_req'] = async_req
        return self.add_sub_group_to_group_with_http_info(scope, code, effective_at, resource_id, **kwargs)  # noqa: E501

    @validate_arguments
    def add_sub_group_to_group_with_http_info(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group to add a portfolio group to.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group to add a portfolio group to. Together with the scope this uniquely identifies the portfolio group.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label from which the sub group will be added to the group.")] = None, resource_id : Annotated[Optional[ResourceId], Field(description="The resource identifier of the portfolio group to add to the portfolio group as a sub group.")] = None, **kwargs) -> ApiResponse:  # noqa: E501
        """[EARLY ACCESS] AddSubGroupToGroup: Add sub group to group  # noqa: E501

        Add a portfolio group to a portfolio group as a sub group.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.add_sub_group_to_group_with_http_info(scope, code, effective_at, resource_id, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the portfolio group to add a portfolio group to. (required)
        :type scope: str
        :param code: The code of the portfolio group to add a portfolio group to. Together with the scope this uniquely identifies the portfolio group. (required)
        :type code: str
        :param effective_at: The effective datetime or cut label from which the sub group will be added to the group.
        :type effective_at: str
        :param resource_id: The resource identifier of the portfolio group to add to the portfolio group as a sub group.
        :type resource_id: ResourceId
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _preload_content: if False, the ApiResponse.data will
                                 be set to none and raw_data will store the
                                 HTTP response body without reading/decoding.
                                 Default is True.
        :type _preload_content: bool, optional
        :param _return_http_data_only: response data instead of ApiResponse
                                       object with status code, headers, etc
        :type _return_http_data_only: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the authentication
                              in the spec for a single request.
        :type _request_auth: dict, optional
        :type _content_type: string, optional: force content-type for the request
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: tuple(PortfolioGroup, status_code(int), headers(HTTPHeaderDict))
        """

        _params = locals()

        _all_params = [
            'scope',
            'code',
            'effective_at',
            'resource_id'
        ]
        _all_params.extend(
            [
                'async_req',
                '_return_http_data_only',
                '_preload_content',
                '_request_timeout',
                '_request_auth',
                '_content_type',
                '_headers',
                'opts'
            ]
        )

        # validate the arguments
        for _key, _val in _params['kwargs'].items():
            if _key not in _all_params:
                raise ApiTypeError(
                    "Got an unexpected keyword argument '%s'"
                    " to method add_sub_group_to_group" % _key
                )
            _params[_key] = _val
        del _params['kwargs']

        _collection_formats = {}

        # process the path parameters
        _path_params = {}
        if _params['scope']:
            _path_params['scope'] = _params['scope']

        if _params['code']:
            _path_params['code'] = _params['code']


        # process the query parameters
        _query_params = []
        if _params.get('effective_at') is not None:  # noqa: E501
            _query_params.append(('effectiveAt', _params['effective_at']))

        # process the header parameters
        _header_params = dict(_params.get('_headers', {}))
        # process the form parameters
        _form_params = []
        _files = {}
        # process the body parameter
        _body_params = None
        if _params['resource_id'] is not None:
            _body_params = _params['resource_id']

        # set the HTTP header `Accept`
        _header_params['Accept'] = self.api_client.select_header_accept(
            ['text/plain', 'application/json', 'text/json'])  # noqa: E501

        # set the HTTP header `Content-Type`
        _content_types_list = _params.get('_content_type',
            self.api_client.select_header_content_type(
                ['application/json-patch+json', 'application/json', 'text/json', 'application/*+json']))
        if _content_types_list:
                _header_params['Content-Type'] = _content_types_list

        # authentication setting
        _auth_settings = ['oauth2']  # noqa: E501

        _response_types_map = {
            '201': "PortfolioGroup",
            '400': "LusidValidationProblemDetails",
        }

        return self.api_client.call_api(
            '/api/portfoliogroups/{scope}/{code}/subgroups', 'POST',
            _path_params,
            _query_params,
            _header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            response_types_map=_response_types_map,
            auth_settings=_auth_settings,
            async_req=_params.get('async_req'),
            _return_http_data_only=_params.get('_return_http_data_only'),  # noqa: E501
            _preload_content=_params.get('_preload_content', True),
            _request_timeout=_params.get('_request_timeout'),
            opts=_params.get('opts'),
            collection_formats=_collection_formats,
            _request_auth=_params.get('_request_auth'))


    @overload
    async def build_transactions_for_portfolio_group(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group. Together with the scope this uniquely identifies               the portfolio group.")], transaction_query_parameters : Annotated[TransactionQueryParameters, Field(description="The query queryParameters which control how the output transactions are built.")], as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to build the transactions. Defaults to return the latest               version of each transaction if not specified.")] = None, filter : Annotated[Optional[StrictStr], Field( description="Expression to filter the result set.               For example, to filter on the Transaction Type, use \"type eq 'Buy'\"               Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.")] = None, property_keys : Annotated[Optional[List[StrictStr]], Field(description="A list of property keys from the \"Instrument\" or \"Transaction\" domain to decorate onto               the transactions. These take the format {domain}/{scope}/{code} e.g. \"Instrument/system/Name\" or               \"Transaction/strategy/quantsignal\".")] = None, limit : Annotated[Optional[StrictInt], Field(description="When paginating, limit the number of returned results to this many. Defaults to 100 if not specified.")] = None, page : Annotated[Optional[StrictStr], Field( description="The pagination token to use to continue listing transactions from a previous call to BuildTransactions.")] = None, data_model_scope : Annotated[Optional[StrictStr], Field( description="The optional scope of a Custom Data Model to use")] = None, data_model_code : Annotated[Optional[StrictStr], Field( description="The optional code of a Custom Data Model to use")] = None, **kwargs) -> VersionedResourceListOfOutputTransaction:  # noqa: E501
        ...

    @overload
    def build_transactions_for_portfolio_group(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group. Together with the scope this uniquely identifies               the portfolio group.")], transaction_query_parameters : Annotated[TransactionQueryParameters, Field(description="The query queryParameters which control how the output transactions are built.")], as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to build the transactions. Defaults to return the latest               version of each transaction if not specified.")] = None, filter : Annotated[Optional[StrictStr], Field( description="Expression to filter the result set.               For example, to filter on the Transaction Type, use \"type eq 'Buy'\"               Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.")] = None, property_keys : Annotated[Optional[List[StrictStr]], Field(description="A list of property keys from the \"Instrument\" or \"Transaction\" domain to decorate onto               the transactions. These take the format {domain}/{scope}/{code} e.g. \"Instrument/system/Name\" or               \"Transaction/strategy/quantsignal\".")] = None, limit : Annotated[Optional[StrictInt], Field(description="When paginating, limit the number of returned results to this many. Defaults to 100 if not specified.")] = None, page : Annotated[Optional[StrictStr], Field( description="The pagination token to use to continue listing transactions from a previous call to BuildTransactions.")] = None, data_model_scope : Annotated[Optional[StrictStr], Field( description="The optional scope of a Custom Data Model to use")] = None, data_model_code : Annotated[Optional[StrictStr], Field( description="The optional code of a Custom Data Model to use")] = None, async_req: Optional[bool]=True, **kwargs) -> VersionedResourceListOfOutputTransaction:  # noqa: E501
        ...

    @validate_arguments
    def build_transactions_for_portfolio_group(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group. Together with the scope this uniquely identifies               the portfolio group.")], transaction_query_parameters : Annotated[TransactionQueryParameters, Field(description="The query queryParameters which control how the output transactions are built.")], as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to build the transactions. Defaults to return the latest               version of each transaction if not specified.")] = None, filter : Annotated[Optional[StrictStr], Field( description="Expression to filter the result set.               For example, to filter on the Transaction Type, use \"type eq 'Buy'\"               Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.")] = None, property_keys : Annotated[Optional[List[StrictStr]], Field(description="A list of property keys from the \"Instrument\" or \"Transaction\" domain to decorate onto               the transactions. These take the format {domain}/{scope}/{code} e.g. \"Instrument/system/Name\" or               \"Transaction/strategy/quantsignal\".")] = None, limit : Annotated[Optional[StrictInt], Field(description="When paginating, limit the number of returned results to this many. Defaults to 100 if not specified.")] = None, page : Annotated[Optional[StrictStr], Field( description="The pagination token to use to continue listing transactions from a previous call to BuildTransactions.")] = None, data_model_scope : Annotated[Optional[StrictStr], Field( description="The optional scope of a Custom Data Model to use")] = None, data_model_code : Annotated[Optional[StrictStr], Field( description="The optional code of a Custom Data Model to use")] = None, async_req: Optional[bool]=None, **kwargs) -> Union[VersionedResourceListOfOutputTransaction, Awaitable[VersionedResourceListOfOutputTransaction]]:  # noqa: E501
        """BuildTransactionsForPortfolioGroup: Build transactions for transaction portfolios in a portfolio group  # noqa: E501

        Build transactions for transaction portfolios in a portfolio group over a given interval of effective time.                When the specified portfolio in a portfolio group is a derived transaction portfolio, the returned set of transactions is the  union set of all transactions of the parent (and any grandparents etc.) and the specified derived transaction portfolio itself.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.build_transactions_for_portfolio_group(scope, code, transaction_query_parameters, as_at, filter, property_keys, limit, page, data_model_scope, data_model_code, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the portfolio group. (required)
        :type scope: str
        :param code: The code of the portfolio group. Together with the scope this uniquely identifies               the portfolio group. (required)
        :type code: str
        :param transaction_query_parameters: The query queryParameters which control how the output transactions are built. (required)
        :type transaction_query_parameters: TransactionQueryParameters
        :param as_at: The asAt datetime at which to build the transactions. Defaults to return the latest               version of each transaction if not specified.
        :type as_at: datetime
        :param filter: Expression to filter the result set.               For example, to filter on the Transaction Type, use \"type eq 'Buy'\"               Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.
        :type filter: str
        :param property_keys: A list of property keys from the \"Instrument\" or \"Transaction\" domain to decorate onto               the transactions. These take the format {domain}/{scope}/{code} e.g. \"Instrument/system/Name\" or               \"Transaction/strategy/quantsignal\".
        :type property_keys: List[str]
        :param limit: When paginating, limit the number of returned results to this many. Defaults to 100 if not specified.
        :type limit: int
        :param page: The pagination token to use to continue listing transactions from a previous call to BuildTransactions.
        :type page: str
        :param data_model_scope: The optional scope of a Custom Data Model to use
        :type data_model_scope: str
        :param data_model_code: The optional code of a Custom Data Model to use
        :type data_model_code: str
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: VersionedResourceListOfOutputTransaction
        """
        kwargs['_return_http_data_only'] = True
        if '_preload_content' in kwargs:
            message = "Error! Please call the build_transactions_for_portfolio_group_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data"  # noqa: E501
            raise ValueError(message)
        if async_req is not None:
            kwargs['async_req'] = async_req
        return self.build_transactions_for_portfolio_group_with_http_info(scope, code, transaction_query_parameters, as_at, filter, property_keys, limit, page, data_model_scope, data_model_code, **kwargs)  # noqa: E501

    @validate_arguments
    def build_transactions_for_portfolio_group_with_http_info(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group. Together with the scope this uniquely identifies               the portfolio group.")], transaction_query_parameters : Annotated[TransactionQueryParameters, Field(description="The query queryParameters which control how the output transactions are built.")], as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to build the transactions. Defaults to return the latest               version of each transaction if not specified.")] = None, filter : Annotated[Optional[StrictStr], Field( description="Expression to filter the result set.               For example, to filter on the Transaction Type, use \"type eq 'Buy'\"               Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.")] = None, property_keys : Annotated[Optional[List[StrictStr]], Field(description="A list of property keys from the \"Instrument\" or \"Transaction\" domain to decorate onto               the transactions. These take the format {domain}/{scope}/{code} e.g. \"Instrument/system/Name\" or               \"Transaction/strategy/quantsignal\".")] = None, limit : Annotated[Optional[StrictInt], Field(description="When paginating, limit the number of returned results to this many. Defaults to 100 if not specified.")] = None, page : Annotated[Optional[StrictStr], Field( description="The pagination token to use to continue listing transactions from a previous call to BuildTransactions.")] = None, data_model_scope : Annotated[Optional[StrictStr], Field( description="The optional scope of a Custom Data Model to use")] = None, data_model_code : Annotated[Optional[StrictStr], Field( description="The optional code of a Custom Data Model to use")] = None, **kwargs) -> ApiResponse:  # noqa: E501
        """BuildTransactionsForPortfolioGroup: Build transactions for transaction portfolios in a portfolio group  # noqa: E501

        Build transactions for transaction portfolios in a portfolio group over a given interval of effective time.                When the specified portfolio in a portfolio group is a derived transaction portfolio, the returned set of transactions is the  union set of all transactions of the parent (and any grandparents etc.) and the specified derived transaction portfolio itself.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.build_transactions_for_portfolio_group_with_http_info(scope, code, transaction_query_parameters, as_at, filter, property_keys, limit, page, data_model_scope, data_model_code, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the portfolio group. (required)
        :type scope: str
        :param code: The code of the portfolio group. Together with the scope this uniquely identifies               the portfolio group. (required)
        :type code: str
        :param transaction_query_parameters: The query queryParameters which control how the output transactions are built. (required)
        :type transaction_query_parameters: TransactionQueryParameters
        :param as_at: The asAt datetime at which to build the transactions. Defaults to return the latest               version of each transaction if not specified.
        :type as_at: datetime
        :param filter: Expression to filter the result set.               For example, to filter on the Transaction Type, use \"type eq 'Buy'\"               Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.
        :type filter: str
        :param property_keys: A list of property keys from the \"Instrument\" or \"Transaction\" domain to decorate onto               the transactions. These take the format {domain}/{scope}/{code} e.g. \"Instrument/system/Name\" or               \"Transaction/strategy/quantsignal\".
        :type property_keys: List[str]
        :param limit: When paginating, limit the number of returned results to this many. Defaults to 100 if not specified.
        :type limit: int
        :param page: The pagination token to use to continue listing transactions from a previous call to BuildTransactions.
        :type page: str
        :param data_model_scope: The optional scope of a Custom Data Model to use
        :type data_model_scope: str
        :param data_model_code: The optional code of a Custom Data Model to use
        :type data_model_code: str
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _preload_content: if False, the ApiResponse.data will
                                 be set to none and raw_data will store the
                                 HTTP response body without reading/decoding.
                                 Default is True.
        :type _preload_content: bool, optional
        :param _return_http_data_only: response data instead of ApiResponse
                                       object with status code, headers, etc
        :type _return_http_data_only: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the authentication
                              in the spec for a single request.
        :type _request_auth: dict, optional
        :type _content_type: string, optional: force content-type for the request
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: tuple(VersionedResourceListOfOutputTransaction, status_code(int), headers(HTTPHeaderDict))
        """

        _params = locals()

        _all_params = [
            'scope',
            'code',
            'transaction_query_parameters',
            'as_at',
            'filter',
            'property_keys',
            'limit',
            'page',
            'data_model_scope',
            'data_model_code'
        ]
        _all_params.extend(
            [
                'async_req',
                '_return_http_data_only',
                '_preload_content',
                '_request_timeout',
                '_request_auth',
                '_content_type',
                '_headers',
                'opts'
            ]
        )

        # validate the arguments
        for _key, _val in _params['kwargs'].items():
            if _key not in _all_params:
                raise ApiTypeError(
                    "Got an unexpected keyword argument '%s'"
                    " to method build_transactions_for_portfolio_group" % _key
                )
            _params[_key] = _val
        del _params['kwargs']

        _collection_formats = {}

        # process the path parameters
        _path_params = {}
        if _params['scope']:
            _path_params['scope'] = _params['scope']

        if _params['code']:
            _path_params['code'] = _params['code']


        # process the query parameters
        _query_params = []
        if _params.get('as_at') is not None:  # noqa: E501
            if isinstance(_params['as_at'], datetime):
                _query_params.append(('asAt', _params['as_at'].strftime(self.api_client.configuration.datetime_format)))
            else:
                _query_params.append(('asAt', _params['as_at']))

        if _params.get('filter') is not None:  # noqa: E501
            _query_params.append(('filter', _params['filter']))

        if _params.get('property_keys') is not None:  # noqa: E501
            _query_params.append(('propertyKeys', _params['property_keys']))
            _collection_formats['propertyKeys'] = 'multi'

        if _params.get('limit') is not None:  # noqa: E501
            _query_params.append(('limit', _params['limit']))

        if _params.get('page') is not None:  # noqa: E501
            _query_params.append(('page', _params['page']))

        if _params.get('data_model_scope') is not None:  # noqa: E501
            _query_params.append(('dataModelScope', _params['data_model_scope']))

        if _params.get('data_model_code') is not None:  # noqa: E501
            _query_params.append(('dataModelCode', _params['data_model_code']))

        # process the header parameters
        _header_params = dict(_params.get('_headers', {}))
        # process the form parameters
        _form_params = []
        _files = {}
        # process the body parameter
        _body_params = None
        if _params['transaction_query_parameters'] is not None:
            _body_params = _params['transaction_query_parameters']

        # set the HTTP header `Accept`
        _header_params['Accept'] = self.api_client.select_header_accept(
            ['text/plain', 'application/json', 'text/json'])  # noqa: E501

        # set the HTTP header `Content-Type`
        _content_types_list = _params.get('_content_type',
            self.api_client.select_header_content_type(
                ['application/json-patch+json', 'application/json', 'text/json', 'application/*+json']))
        if _content_types_list:
                _header_params['Content-Type'] = _content_types_list

        # authentication setting
        _auth_settings = ['oauth2']  # noqa: E501

        _response_types_map = {
            '200': "VersionedResourceListOfOutputTransaction",
            '400': "LusidValidationProblemDetails",
        }

        return self.api_client.call_api(
            '/api/portfoliogroups/{scope}/{code}/transactions/$build', 'POST',
            _path_params,
            _query_params,
            _header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            response_types_map=_response_types_map,
            auth_settings=_auth_settings,
            async_req=_params.get('async_req'),
            _return_http_data_only=_params.get('_return_http_data_only'),  # noqa: E501
            _preload_content=_params.get('_preload_content', True),
            _request_timeout=_params.get('_request_timeout'),
            opts=_params.get('opts'),
            collection_formats=_collection_formats,
            _request_auth=_params.get('_request_auth'))


    @overload
    async def create_portfolio_group(self, scope : Annotated[StrictStr, Field(..., description="The scope that the portfolio group will be created in.")], create_portfolio_group_request : Annotated[Optional[CreatePortfolioGroupRequest], Field(description="The definition and details of the portfolio group.")] = None, **kwargs) -> PortfolioGroup:  # noqa: E501
        ...

    @overload
    def create_portfolio_group(self, scope : Annotated[StrictStr, Field(..., description="The scope that the portfolio group will be created in.")], create_portfolio_group_request : Annotated[Optional[CreatePortfolioGroupRequest], Field(description="The definition and details of the portfolio group.")] = None, async_req: Optional[bool]=True, **kwargs) -> PortfolioGroup:  # noqa: E501
        ...

    @validate_arguments
    def create_portfolio_group(self, scope : Annotated[StrictStr, Field(..., description="The scope that the portfolio group will be created in.")], create_portfolio_group_request : Annotated[Optional[CreatePortfolioGroupRequest], Field(description="The definition and details of the portfolio group.")] = None, async_req: Optional[bool]=None, **kwargs) -> Union[PortfolioGroup, Awaitable[PortfolioGroup]]:  # noqa: E501
        """CreatePortfolioGroup: Create portfolio group  # noqa: E501

        Create a portfolio group in a specific scope.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.create_portfolio_group(scope, create_portfolio_group_request, async_req=True)
        >>> result = thread.get()

        :param scope: The scope that the portfolio group will be created in. (required)
        :type scope: str
        :param create_portfolio_group_request: The definition and details of the portfolio group.
        :type create_portfolio_group_request: CreatePortfolioGroupRequest
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: PortfolioGroup
        """
        kwargs['_return_http_data_only'] = True
        if '_preload_content' in kwargs:
            message = "Error! Please call the create_portfolio_group_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data"  # noqa: E501
            raise ValueError(message)
        if async_req is not None:
            kwargs['async_req'] = async_req
        return self.create_portfolio_group_with_http_info(scope, create_portfolio_group_request, **kwargs)  # noqa: E501

    @validate_arguments
    def create_portfolio_group_with_http_info(self, scope : Annotated[StrictStr, Field(..., description="The scope that the portfolio group will be created in.")], create_portfolio_group_request : Annotated[Optional[CreatePortfolioGroupRequest], Field(description="The definition and details of the portfolio group.")] = None, **kwargs) -> ApiResponse:  # noqa: E501
        """CreatePortfolioGroup: Create portfolio group  # noqa: E501

        Create a portfolio group in a specific scope.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.create_portfolio_group_with_http_info(scope, create_portfolio_group_request, async_req=True)
        >>> result = thread.get()

        :param scope: The scope that the portfolio group will be created in. (required)
        :type scope: str
        :param create_portfolio_group_request: The definition and details of the portfolio group.
        :type create_portfolio_group_request: CreatePortfolioGroupRequest
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _preload_content: if False, the ApiResponse.data will
                                 be set to none and raw_data will store the
                                 HTTP response body without reading/decoding.
                                 Default is True.
        :type _preload_content: bool, optional
        :param _return_http_data_only: response data instead of ApiResponse
                                       object with status code, headers, etc
        :type _return_http_data_only: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the authentication
                              in the spec for a single request.
        :type _request_auth: dict, optional
        :type _content_type: string, optional: force content-type for the request
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: tuple(PortfolioGroup, status_code(int), headers(HTTPHeaderDict))
        """

        _params = locals()

        _all_params = [
            'scope',
            'create_portfolio_group_request'
        ]
        _all_params.extend(
            [
                'async_req',
                '_return_http_data_only',
                '_preload_content',
                '_request_timeout',
                '_request_auth',
                '_content_type',
                '_headers',
                'opts'
            ]
        )

        # validate the arguments
        for _key, _val in _params['kwargs'].items():
            if _key not in _all_params:
                raise ApiTypeError(
                    "Got an unexpected keyword argument '%s'"
                    " to method create_portfolio_group" % _key
                )
            _params[_key] = _val
        del _params['kwargs']

        _collection_formats = {}

        # process the path parameters
        _path_params = {}
        if _params['scope']:
            _path_params['scope'] = _params['scope']


        # process the query parameters
        _query_params = []
        # process the header parameters
        _header_params = dict(_params.get('_headers', {}))
        # process the form parameters
        _form_params = []
        _files = {}
        # process the body parameter
        _body_params = None
        if _params['create_portfolio_group_request'] is not None:
            _body_params = _params['create_portfolio_group_request']

        # set the HTTP header `Accept`
        _header_params['Accept'] = self.api_client.select_header_accept(
            ['text/plain', 'application/json', 'text/json'])  # noqa: E501

        # set the HTTP header `Content-Type`
        _content_types_list = _params.get('_content_type',
            self.api_client.select_header_content_type(
                ['application/json-patch+json', 'application/json', 'text/json', 'application/*+json']))
        if _content_types_list:
                _header_params['Content-Type'] = _content_types_list

        # authentication setting
        _auth_settings = ['oauth2']  # noqa: E501

        _response_types_map = {
            '201': "PortfolioGroup",
            '400': "LusidValidationProblemDetails",
        }

        return self.api_client.call_api(
            '/api/portfoliogroups/{scope}', 'POST',
            _path_params,
            _query_params,
            _header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            response_types_map=_response_types_map,
            auth_settings=_auth_settings,
            async_req=_params.get('async_req'),
            _return_http_data_only=_params.get('_return_http_data_only'),  # noqa: E501
            _preload_content=_params.get('_preload_content', True),
            _request_timeout=_params.get('_request_timeout'),
            opts=_params.get('opts'),
            collection_formats=_collection_formats,
            _request_auth=_params.get('_request_auth'))


    @overload
    async def delete_group_properties(self, scope : Annotated[StrictStr, Field(..., description="The scope of the group to delete properties from.")], code : Annotated[StrictStr, Field(..., description="The code of the group to delete properties from. Together with the scope this uniquely identifies the group.")], request_body : Annotated[List[StrictStr], Field(description="The property keys of the properties to delete. These take the format              {domain}/{scope}/{code} e.g. \"PortfolioGroup/Manager/Id\". Each property must be from the \"PortfolioGroup\" domain.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label at which to delete time-variant properties from.              The property must exist at the specified 'effectiveAt' datetime. If the 'effectiveAt' is not provided or is              before the time-variant property exists then a failure is returned. Do not specify this parameter if any of              the properties to delete are perpetual.")] = None, **kwargs) -> DeletedEntityResponse:  # noqa: E501
        ...

    @overload
    def delete_group_properties(self, scope : Annotated[StrictStr, Field(..., description="The scope of the group to delete properties from.")], code : Annotated[StrictStr, Field(..., description="The code of the group to delete properties from. Together with the scope this uniquely identifies the group.")], request_body : Annotated[List[StrictStr], Field(description="The property keys of the properties to delete. These take the format              {domain}/{scope}/{code} e.g. \"PortfolioGroup/Manager/Id\". Each property must be from the \"PortfolioGroup\" domain.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label at which to delete time-variant properties from.              The property must exist at the specified 'effectiveAt' datetime. If the 'effectiveAt' is not provided or is              before the time-variant property exists then a failure is returned. Do not specify this parameter if any of              the properties to delete are perpetual.")] = None, async_req: Optional[bool]=True, **kwargs) -> DeletedEntityResponse:  # noqa: E501
        ...

    @validate_arguments
    def delete_group_properties(self, scope : Annotated[StrictStr, Field(..., description="The scope of the group to delete properties from.")], code : Annotated[StrictStr, Field(..., description="The code of the group to delete properties from. Together with the scope this uniquely identifies the group.")], request_body : Annotated[List[StrictStr], Field(description="The property keys of the properties to delete. These take the format              {domain}/{scope}/{code} e.g. \"PortfolioGroup/Manager/Id\". Each property must be from the \"PortfolioGroup\" domain.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label at which to delete time-variant properties from.              The property must exist at the specified 'effectiveAt' datetime. If the 'effectiveAt' is not provided or is              before the time-variant property exists then a failure is returned. Do not specify this parameter if any of              the properties to delete are perpetual.")] = None, async_req: Optional[bool]=None, **kwargs) -> Union[DeletedEntityResponse, Awaitable[DeletedEntityResponse]]:  # noqa: E501
        """[EARLY ACCESS] DeleteGroupProperties: Delete group properties  # noqa: E501

        Delete one or more properties from a single portfolio group. If the properties are time variant then an effective date time from which the properties  will be deleted must be specified. If the properties are perpetual then it is invalid to specify an effective date time for deletion.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.delete_group_properties(scope, code, request_body, effective_at, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the group to delete properties from. (required)
        :type scope: str
        :param code: The code of the group to delete properties from. Together with the scope this uniquely identifies the group. (required)
        :type code: str
        :param request_body: The property keys of the properties to delete. These take the format              {domain}/{scope}/{code} e.g. \"PortfolioGroup/Manager/Id\". Each property must be from the \"PortfolioGroup\" domain. (required)
        :type request_body: List[str]
        :param effective_at: The effective datetime or cut label at which to delete time-variant properties from.              The property must exist at the specified 'effectiveAt' datetime. If the 'effectiveAt' is not provided or is              before the time-variant property exists then a failure is returned. Do not specify this parameter if any of              the properties to delete are perpetual.
        :type effective_at: str
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: DeletedEntityResponse
        """
        kwargs['_return_http_data_only'] = True
        if '_preload_content' in kwargs:
            message = "Error! Please call the delete_group_properties_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data"  # noqa: E501
            raise ValueError(message)
        if async_req is not None:
            kwargs['async_req'] = async_req
        return self.delete_group_properties_with_http_info(scope, code, request_body, effective_at, **kwargs)  # noqa: E501

    @validate_arguments
    def delete_group_properties_with_http_info(self, scope : Annotated[StrictStr, Field(..., description="The scope of the group to delete properties from.")], code : Annotated[StrictStr, Field(..., description="The code of the group to delete properties from. Together with the scope this uniquely identifies the group.")], request_body : Annotated[List[StrictStr], Field(description="The property keys of the properties to delete. These take the format              {domain}/{scope}/{code} e.g. \"PortfolioGroup/Manager/Id\". Each property must be from the \"PortfolioGroup\" domain.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label at which to delete time-variant properties from.              The property must exist at the specified 'effectiveAt' datetime. If the 'effectiveAt' is not provided or is              before the time-variant property exists then a failure is returned. Do not specify this parameter if any of              the properties to delete are perpetual.")] = None, **kwargs) -> ApiResponse:  # noqa: E501
        """[EARLY ACCESS] DeleteGroupProperties: Delete group properties  # noqa: E501

        Delete one or more properties from a single portfolio group. If the properties are time variant then an effective date time from which the properties  will be deleted must be specified. If the properties are perpetual then it is invalid to specify an effective date time for deletion.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.delete_group_properties_with_http_info(scope, code, request_body, effective_at, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the group to delete properties from. (required)
        :type scope: str
        :param code: The code of the group to delete properties from. Together with the scope this uniquely identifies the group. (required)
        :type code: str
        :param request_body: The property keys of the properties to delete. These take the format              {domain}/{scope}/{code} e.g. \"PortfolioGroup/Manager/Id\". Each property must be from the \"PortfolioGroup\" domain. (required)
        :type request_body: List[str]
        :param effective_at: The effective datetime or cut label at which to delete time-variant properties from.              The property must exist at the specified 'effectiveAt' datetime. If the 'effectiveAt' is not provided or is              before the time-variant property exists then a failure is returned. Do not specify this parameter if any of              the properties to delete are perpetual.
        :type effective_at: str
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _preload_content: if False, the ApiResponse.data will
                                 be set to none and raw_data will store the
                                 HTTP response body without reading/decoding.
                                 Default is True.
        :type _preload_content: bool, optional
        :param _return_http_data_only: response data instead of ApiResponse
                                       object with status code, headers, etc
        :type _return_http_data_only: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the authentication
                              in the spec for a single request.
        :type _request_auth: dict, optional
        :type _content_type: string, optional: force content-type for the request
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: tuple(DeletedEntityResponse, status_code(int), headers(HTTPHeaderDict))
        """

        _params = locals()

        _all_params = [
            'scope',
            'code',
            'request_body',
            'effective_at'
        ]
        _all_params.extend(
            [
                'async_req',
                '_return_http_data_only',
                '_preload_content',
                '_request_timeout',
                '_request_auth',
                '_content_type',
                '_headers',
                'opts'
            ]
        )

        # validate the arguments
        for _key, _val in _params['kwargs'].items():
            if _key not in _all_params:
                raise ApiTypeError(
                    "Got an unexpected keyword argument '%s'"
                    " to method delete_group_properties" % _key
                )
            _params[_key] = _val
        del _params['kwargs']

        _collection_formats = {}

        # process the path parameters
        _path_params = {}
        if _params['scope']:
            _path_params['scope'] = _params['scope']

        if _params['code']:
            _path_params['code'] = _params['code']


        # process the query parameters
        _query_params = []
        if _params.get('effective_at') is not None:  # noqa: E501
            _query_params.append(('effectiveAt', _params['effective_at']))

        # process the header parameters
        _header_params = dict(_params.get('_headers', {}))
        # process the form parameters
        _form_params = []
        _files = {}
        # process the body parameter
        _body_params = None
        if _params['request_body'] is not None:
            _body_params = _params['request_body']

        # set the HTTP header `Accept`
        _header_params['Accept'] = self.api_client.select_header_accept(
            ['text/plain', 'application/json', 'text/json'])  # noqa: E501

        # set the HTTP header `Content-Type`
        _content_types_list = _params.get('_content_type',
            self.api_client.select_header_content_type(
                ['application/json-patch+json', 'application/json', 'text/json', 'application/*+json']))
        if _content_types_list:
                _header_params['Content-Type'] = _content_types_list

        # authentication setting
        _auth_settings = ['oauth2']  # noqa: E501

        _response_types_map = {
            '200': "DeletedEntityResponse",
            '400': "LusidValidationProblemDetails",
        }

        return self.api_client.call_api(
            '/api/portfoliogroups/{scope}/{code}/properties/$delete', 'POST',
            _path_params,
            _query_params,
            _header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            response_types_map=_response_types_map,
            auth_settings=_auth_settings,
            async_req=_params.get('async_req'),
            _return_http_data_only=_params.get('_return_http_data_only'),  # noqa: E501
            _preload_content=_params.get('_preload_content', True),
            _request_timeout=_params.get('_request_timeout'),
            opts=_params.get('opts'),
            collection_formats=_collection_formats,
            _request_auth=_params.get('_request_auth'))


    @overload
    async def delete_key_from_portfolio_group_access_metadata(self, scope : Annotated[StrictStr, Field(..., description="The scope of the Portfolio Group")], code : Annotated[StrictStr, Field(..., description="The Portfolio Group code")], metadata_key : Annotated[StrictStr, Field(..., description="Key of the Access Metadata entry to delete")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective date to delete at, if this is not supplied, it will delete all data found")] = None, effective_until : Annotated[Optional[datetime], Field(description="The effective date until which the delete is valid. If not supplied this will be valid indefinitely, or until the next 'effectiveAt' date of the Access Metadata")] = None, **kwargs) -> DeletedEntityResponse:  # noqa: E501
        ...

    @overload
    def delete_key_from_portfolio_group_access_metadata(self, scope : Annotated[StrictStr, Field(..., description="The scope of the Portfolio Group")], code : Annotated[StrictStr, Field(..., description="The Portfolio Group code")], metadata_key : Annotated[StrictStr, Field(..., description="Key of the Access Metadata entry to delete")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective date to delete at, if this is not supplied, it will delete all data found")] = None, effective_until : Annotated[Optional[datetime], Field(description="The effective date until which the delete is valid. If not supplied this will be valid indefinitely, or until the next 'effectiveAt' date of the Access Metadata")] = None, async_req: Optional[bool]=True, **kwargs) -> DeletedEntityResponse:  # noqa: E501
        ...

    @validate_arguments
    def delete_key_from_portfolio_group_access_metadata(self, scope : Annotated[StrictStr, Field(..., description="The scope of the Portfolio Group")], code : Annotated[StrictStr, Field(..., description="The Portfolio Group code")], metadata_key : Annotated[StrictStr, Field(..., description="Key of the Access Metadata entry to delete")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective date to delete at, if this is not supplied, it will delete all data found")] = None, effective_until : Annotated[Optional[datetime], Field(description="The effective date until which the delete is valid. If not supplied this will be valid indefinitely, or until the next 'effectiveAt' date of the Access Metadata")] = None, async_req: Optional[bool]=None, **kwargs) -> Union[DeletedEntityResponse, Awaitable[DeletedEntityResponse]]:  # noqa: E501
        """[EARLY ACCESS] DeleteKeyFromPortfolioGroupAccessMetadata: Delete a Portfolio Group Access Metadata entry  # noqa: E501

        Deletes the Portfolio Group Access Metadata entry that exactly matches the provided identifier parts.    It is important to always check to verify success (or failure).  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.delete_key_from_portfolio_group_access_metadata(scope, code, metadata_key, effective_at, effective_until, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the Portfolio Group (required)
        :type scope: str
        :param code: The Portfolio Group code (required)
        :type code: str
        :param metadata_key: Key of the Access Metadata entry to delete (required)
        :type metadata_key: str
        :param effective_at: The effective date to delete at, if this is not supplied, it will delete all data found
        :type effective_at: str
        :param effective_until: The effective date until which the delete is valid. If not supplied this will be valid indefinitely, or until the next 'effectiveAt' date of the Access Metadata
        :type effective_until: datetime
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: DeletedEntityResponse
        """
        kwargs['_return_http_data_only'] = True
        if '_preload_content' in kwargs:
            message = "Error! Please call the delete_key_from_portfolio_group_access_metadata_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data"  # noqa: E501
            raise ValueError(message)
        if async_req is not None:
            kwargs['async_req'] = async_req
        return self.delete_key_from_portfolio_group_access_metadata_with_http_info(scope, code, metadata_key, effective_at, effective_until, **kwargs)  # noqa: E501

    @validate_arguments
    def delete_key_from_portfolio_group_access_metadata_with_http_info(self, scope : Annotated[StrictStr, Field(..., description="The scope of the Portfolio Group")], code : Annotated[StrictStr, Field(..., description="The Portfolio Group code")], metadata_key : Annotated[StrictStr, Field(..., description="Key of the Access Metadata entry to delete")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective date to delete at, if this is not supplied, it will delete all data found")] = None, effective_until : Annotated[Optional[datetime], Field(description="The effective date until which the delete is valid. If not supplied this will be valid indefinitely, or until the next 'effectiveAt' date of the Access Metadata")] = None, **kwargs) -> ApiResponse:  # noqa: E501
        """[EARLY ACCESS] DeleteKeyFromPortfolioGroupAccessMetadata: Delete a Portfolio Group Access Metadata entry  # noqa: E501

        Deletes the Portfolio Group Access Metadata entry that exactly matches the provided identifier parts.    It is important to always check to verify success (or failure).  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.delete_key_from_portfolio_group_access_metadata_with_http_info(scope, code, metadata_key, effective_at, effective_until, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the Portfolio Group (required)
        :type scope: str
        :param code: The Portfolio Group code (required)
        :type code: str
        :param metadata_key: Key of the Access Metadata entry to delete (required)
        :type metadata_key: str
        :param effective_at: The effective date to delete at, if this is not supplied, it will delete all data found
        :type effective_at: str
        :param effective_until: The effective date until which the delete is valid. If not supplied this will be valid indefinitely, or until the next 'effectiveAt' date of the Access Metadata
        :type effective_until: datetime
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _preload_content: if False, the ApiResponse.data will
                                 be set to none and raw_data will store the
                                 HTTP response body without reading/decoding.
                                 Default is True.
        :type _preload_content: bool, optional
        :param _return_http_data_only: response data instead of ApiResponse
                                       object with status code, headers, etc
        :type _return_http_data_only: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the authentication
                              in the spec for a single request.
        :type _request_auth: dict, optional
        :type _content_type: string, optional: force content-type for the request
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: tuple(DeletedEntityResponse, status_code(int), headers(HTTPHeaderDict))
        """

        _params = locals()

        _all_params = [
            'scope',
            'code',
            'metadata_key',
            'effective_at',
            'effective_until'
        ]
        _all_params.extend(
            [
                'async_req',
                '_return_http_data_only',
                '_preload_content',
                '_request_timeout',
                '_request_auth',
                '_content_type',
                '_headers',
                'opts'
            ]
        )

        # validate the arguments
        for _key, _val in _params['kwargs'].items():
            if _key not in _all_params:
                raise ApiTypeError(
                    "Got an unexpected keyword argument '%s'"
                    " to method delete_key_from_portfolio_group_access_metadata" % _key
                )
            _params[_key] = _val
        del _params['kwargs']

        _collection_formats = {}

        # process the path parameters
        _path_params = {}
        if _params['scope']:
            _path_params['scope'] = _params['scope']

        if _params['code']:
            _path_params['code'] = _params['code']

        if _params['metadata_key']:
            _path_params['metadataKey'] = _params['metadata_key']


        # process the query parameters
        _query_params = []
        if _params.get('effective_at') is not None:  # noqa: E501
            _query_params.append(('effectiveAt', _params['effective_at']))

        if _params.get('effective_until') is not None:  # noqa: E501
            if isinstance(_params['effective_until'], datetime):
                _query_params.append(('effectiveUntil', _params['effective_until'].strftime(self.api_client.configuration.datetime_format)))
            else:
                _query_params.append(('effectiveUntil', _params['effective_until']))

        # process the header parameters
        _header_params = dict(_params.get('_headers', {}))
        # process the form parameters
        _form_params = []
        _files = {}
        # process the body parameter
        _body_params = None
        # set the HTTP header `Accept`
        _header_params['Accept'] = self.api_client.select_header_accept(
            ['text/plain', 'application/json', 'text/json'])  # noqa: E501

        # authentication setting
        _auth_settings = ['oauth2']  # noqa: E501

        _response_types_map = {
            '200': "DeletedEntityResponse",
            '400': "LusidValidationProblemDetails",
        }

        return self.api_client.call_api(
            '/api/portfoliogroups/{scope}/{code}/metadata/{metadataKey}', 'DELETE',
            _path_params,
            _query_params,
            _header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            response_types_map=_response_types_map,
            auth_settings=_auth_settings,
            async_req=_params.get('async_req'),
            _return_http_data_only=_params.get('_return_http_data_only'),  # noqa: E501
            _preload_content=_params.get('_preload_content', True),
            _request_timeout=_params.get('_request_timeout'),
            opts=_params.get('opts'),
            collection_formats=_collection_formats,
            _request_auth=_params.get('_request_auth'))


    @overload
    async def delete_portfolio_from_group(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group to remove the portfolio from.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group to remove the portfolio from. Together with the scope this uniquely identifies the portfolio group.")], portfolio_scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio being removed from the portfolio group.")], portfolio_code : Annotated[StrictStr, Field(..., description="The code of the portfolio being removed from the portfolio group. Together with the scope this uniquely identifies the portfolio to remove.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label from which the portfolio will be removed from the portfolio group.")] = None, **kwargs) -> PortfolioGroup:  # noqa: E501
        ...

    @overload
    def delete_portfolio_from_group(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group to remove the portfolio from.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group to remove the portfolio from. Together with the scope this uniquely identifies the portfolio group.")], portfolio_scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio being removed from the portfolio group.")], portfolio_code : Annotated[StrictStr, Field(..., description="The code of the portfolio being removed from the portfolio group. Together with the scope this uniquely identifies the portfolio to remove.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label from which the portfolio will be removed from the portfolio group.")] = None, async_req: Optional[bool]=True, **kwargs) -> PortfolioGroup:  # noqa: E501
        ...

    @validate_arguments
    def delete_portfolio_from_group(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group to remove the portfolio from.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group to remove the portfolio from. Together with the scope this uniquely identifies the portfolio group.")], portfolio_scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio being removed from the portfolio group.")], portfolio_code : Annotated[StrictStr, Field(..., description="The code of the portfolio being removed from the portfolio group. Together with the scope this uniquely identifies the portfolio to remove.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label from which the portfolio will be removed from the portfolio group.")] = None, async_req: Optional[bool]=None, **kwargs) -> Union[PortfolioGroup, Awaitable[PortfolioGroup]]:  # noqa: E501
        """[EARLY ACCESS] DeletePortfolioFromGroup: Delete portfolio from group  # noqa: E501

        Remove a single portfolio from a portfolio group.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.delete_portfolio_from_group(scope, code, portfolio_scope, portfolio_code, effective_at, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the portfolio group to remove the portfolio from. (required)
        :type scope: str
        :param code: The code of the portfolio group to remove the portfolio from. Together with the scope this uniquely identifies the portfolio group. (required)
        :type code: str
        :param portfolio_scope: The scope of the portfolio being removed from the portfolio group. (required)
        :type portfolio_scope: str
        :param portfolio_code: The code of the portfolio being removed from the portfolio group. Together with the scope this uniquely identifies the portfolio to remove. (required)
        :type portfolio_code: str
        :param effective_at: The effective datetime or cut label from which the portfolio will be removed from the portfolio group.
        :type effective_at: str
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: PortfolioGroup
        """
        kwargs['_return_http_data_only'] = True
        if '_preload_content' in kwargs:
            message = "Error! Please call the delete_portfolio_from_group_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data"  # noqa: E501
            raise ValueError(message)
        if async_req is not None:
            kwargs['async_req'] = async_req
        return self.delete_portfolio_from_group_with_http_info(scope, code, portfolio_scope, portfolio_code, effective_at, **kwargs)  # noqa: E501

    @validate_arguments
    def delete_portfolio_from_group_with_http_info(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group to remove the portfolio from.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group to remove the portfolio from. Together with the scope this uniquely identifies the portfolio group.")], portfolio_scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio being removed from the portfolio group.")], portfolio_code : Annotated[StrictStr, Field(..., description="The code of the portfolio being removed from the portfolio group. Together with the scope this uniquely identifies the portfolio to remove.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label from which the portfolio will be removed from the portfolio group.")] = None, **kwargs) -> ApiResponse:  # noqa: E501
        """[EARLY ACCESS] DeletePortfolioFromGroup: Delete portfolio from group  # noqa: E501

        Remove a single portfolio from a portfolio group.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.delete_portfolio_from_group_with_http_info(scope, code, portfolio_scope, portfolio_code, effective_at, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the portfolio group to remove the portfolio from. (required)
        :type scope: str
        :param code: The code of the portfolio group to remove the portfolio from. Together with the scope this uniquely identifies the portfolio group. (required)
        :type code: str
        :param portfolio_scope: The scope of the portfolio being removed from the portfolio group. (required)
        :type portfolio_scope: str
        :param portfolio_code: The code of the portfolio being removed from the portfolio group. Together with the scope this uniquely identifies the portfolio to remove. (required)
        :type portfolio_code: str
        :param effective_at: The effective datetime or cut label from which the portfolio will be removed from the portfolio group.
        :type effective_at: str
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _preload_content: if False, the ApiResponse.data will
                                 be set to none and raw_data will store the
                                 HTTP response body without reading/decoding.
                                 Default is True.
        :type _preload_content: bool, optional
        :param _return_http_data_only: response data instead of ApiResponse
                                       object with status code, headers, etc
        :type _return_http_data_only: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the authentication
                              in the spec for a single request.
        :type _request_auth: dict, optional
        :type _content_type: string, optional: force content-type for the request
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: tuple(PortfolioGroup, status_code(int), headers(HTTPHeaderDict))
        """

        _params = locals()

        _all_params = [
            'scope',
            'code',
            'portfolio_scope',
            'portfolio_code',
            'effective_at'
        ]
        _all_params.extend(
            [
                'async_req',
                '_return_http_data_only',
                '_preload_content',
                '_request_timeout',
                '_request_auth',
                '_content_type',
                '_headers',
                'opts'
            ]
        )

        # validate the arguments
        for _key, _val in _params['kwargs'].items():
            if _key not in _all_params:
                raise ApiTypeError(
                    "Got an unexpected keyword argument '%s'"
                    " to method delete_portfolio_from_group" % _key
                )
            _params[_key] = _val
        del _params['kwargs']

        _collection_formats = {}

        # process the path parameters
        _path_params = {}
        if _params['scope']:
            _path_params['scope'] = _params['scope']

        if _params['code']:
            _path_params['code'] = _params['code']

        if _params['portfolio_scope']:
            _path_params['portfolioScope'] = _params['portfolio_scope']

        if _params['portfolio_code']:
            _path_params['portfolioCode'] = _params['portfolio_code']


        # process the query parameters
        _query_params = []
        if _params.get('effective_at') is not None:  # noqa: E501
            _query_params.append(('effectiveAt', _params['effective_at']))

        # process the header parameters
        _header_params = dict(_params.get('_headers', {}))
        # process the form parameters
        _form_params = []
        _files = {}
        # process the body parameter
        _body_params = None
        # set the HTTP header `Accept`
        _header_params['Accept'] = self.api_client.select_header_accept(
            ['text/plain', 'application/json', 'text/json'])  # noqa: E501

        # authentication setting
        _auth_settings = ['oauth2']  # noqa: E501

        _response_types_map = {
            '200': "PortfolioGroup",
            '400': "LusidValidationProblemDetails",
        }

        return self.api_client.call_api(
            '/api/portfoliogroups/{scope}/{code}/portfolios/{portfolioScope}/{portfolioCode}', 'DELETE',
            _path_params,
            _query_params,
            _header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            response_types_map=_response_types_map,
            auth_settings=_auth_settings,
            async_req=_params.get('async_req'),
            _return_http_data_only=_params.get('_return_http_data_only'),  # noqa: E501
            _preload_content=_params.get('_preload_content', True),
            _request_timeout=_params.get('_request_timeout'),
            opts=_params.get('opts'),
            collection_formats=_collection_formats,
            _request_auth=_params.get('_request_auth'))


    @overload
    async def delete_portfolio_group(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group to delete.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group to delete. Together with the scope this uniquely identifies the portfolio group to delete.")], **kwargs) -> DeletedEntityResponse:  # noqa: E501
        ...

    @overload
    def delete_portfolio_group(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group to delete.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group to delete. Together with the scope this uniquely identifies the portfolio group to delete.")], async_req: Optional[bool]=True, **kwargs) -> DeletedEntityResponse:  # noqa: E501
        ...

    @validate_arguments
    def delete_portfolio_group(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group to delete.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group to delete. Together with the scope this uniquely identifies the portfolio group to delete.")], async_req: Optional[bool]=None, **kwargs) -> Union[DeletedEntityResponse, Awaitable[DeletedEntityResponse]]:  # noqa: E501
        """[EARLY ACCESS] DeletePortfolioGroup: Delete portfolio group  # noqa: E501

        Delete a single portfolio group. A portfolio group can be deleted while it still contains portfolios or sub groups.  In this case any portfolios or sub groups contained in this group will not be deleted, however they will no longer be grouped together by this portfolio group.  The deletion will be valid from the portfolio group's creation datetime, ie. the portfolio group will no longer exist at any effective datetime from the asAt datetime of deletion.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.delete_portfolio_group(scope, code, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the portfolio group to delete. (required)
        :type scope: str
        :param code: The code of the portfolio group to delete. Together with the scope this uniquely identifies the portfolio group to delete. (required)
        :type code: str
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: DeletedEntityResponse
        """
        kwargs['_return_http_data_only'] = True
        if '_preload_content' in kwargs:
            message = "Error! Please call the delete_portfolio_group_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data"  # noqa: E501
            raise ValueError(message)
        if async_req is not None:
            kwargs['async_req'] = async_req
        return self.delete_portfolio_group_with_http_info(scope, code, **kwargs)  # noqa: E501

    @validate_arguments
    def delete_portfolio_group_with_http_info(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group to delete.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group to delete. Together with the scope this uniquely identifies the portfolio group to delete.")], **kwargs) -> ApiResponse:  # noqa: E501
        """[EARLY ACCESS] DeletePortfolioGroup: Delete portfolio group  # noqa: E501

        Delete a single portfolio group. A portfolio group can be deleted while it still contains portfolios or sub groups.  In this case any portfolios or sub groups contained in this group will not be deleted, however they will no longer be grouped together by this portfolio group.  The deletion will be valid from the portfolio group's creation datetime, ie. the portfolio group will no longer exist at any effective datetime from the asAt datetime of deletion.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.delete_portfolio_group_with_http_info(scope, code, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the portfolio group to delete. (required)
        :type scope: str
        :param code: The code of the portfolio group to delete. Together with the scope this uniquely identifies the portfolio group to delete. (required)
        :type code: str
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _preload_content: if False, the ApiResponse.data will
                                 be set to none and raw_data will store the
                                 HTTP response body without reading/decoding.
                                 Default is True.
        :type _preload_content: bool, optional
        :param _return_http_data_only: response data instead of ApiResponse
                                       object with status code, headers, etc
        :type _return_http_data_only: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the authentication
                              in the spec for a single request.
        :type _request_auth: dict, optional
        :type _content_type: string, optional: force content-type for the request
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: tuple(DeletedEntityResponse, status_code(int), headers(HTTPHeaderDict))
        """

        _params = locals()

        _all_params = [
            'scope',
            'code'
        ]
        _all_params.extend(
            [
                'async_req',
                '_return_http_data_only',
                '_preload_content',
                '_request_timeout',
                '_request_auth',
                '_content_type',
                '_headers',
                'opts'
            ]
        )

        # validate the arguments
        for _key, _val in _params['kwargs'].items():
            if _key not in _all_params:
                raise ApiTypeError(
                    "Got an unexpected keyword argument '%s'"
                    " to method delete_portfolio_group" % _key
                )
            _params[_key] = _val
        del _params['kwargs']

        _collection_formats = {}

        # process the path parameters
        _path_params = {}
        if _params['scope']:
            _path_params['scope'] = _params['scope']

        if _params['code']:
            _path_params['code'] = _params['code']


        # process the query parameters
        _query_params = []
        # process the header parameters
        _header_params = dict(_params.get('_headers', {}))
        # process the form parameters
        _form_params = []
        _files = {}
        # process the body parameter
        _body_params = None
        # set the HTTP header `Accept`
        _header_params['Accept'] = self.api_client.select_header_accept(
            ['text/plain', 'application/json', 'text/json'])  # noqa: E501

        # authentication setting
        _auth_settings = ['oauth2']  # noqa: E501

        _response_types_map = {
            '200': "DeletedEntityResponse",
            '400': "LusidValidationProblemDetails",
        }

        return self.api_client.call_api(
            '/api/portfoliogroups/{scope}/{code}', 'DELETE',
            _path_params,
            _query_params,
            _header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            response_types_map=_response_types_map,
            auth_settings=_auth_settings,
            async_req=_params.get('async_req'),
            _return_http_data_only=_params.get('_return_http_data_only'),  # noqa: E501
            _preload_content=_params.get('_preload_content', True),
            _request_timeout=_params.get('_request_timeout'),
            opts=_params.get('opts'),
            collection_formats=_collection_formats,
            _request_auth=_params.get('_request_auth'))


    @overload
    async def delete_sub_group_from_group(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group to remove the sub group from.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group to remove the sub group from. Together with the scope this uniquely identifies the portfolio group.")], subgroup_scope : Annotated[StrictStr, Field(..., description="The scope of the sub group to remove from the portfolio group.")], subgroup_code : Annotated[StrictStr, Field(..., description="The code of the sub group to remove from the portfolio group. Together with the scope this uniquely identifies the sub group.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label from which the sub group will be removed from the portfolio group.")] = None, **kwargs) -> PortfolioGroup:  # noqa: E501
        ...

    @overload
    def delete_sub_group_from_group(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group to remove the sub group from.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group to remove the sub group from. Together with the scope this uniquely identifies the portfolio group.")], subgroup_scope : Annotated[StrictStr, Field(..., description="The scope of the sub group to remove from the portfolio group.")], subgroup_code : Annotated[StrictStr, Field(..., description="The code of the sub group to remove from the portfolio group. Together with the scope this uniquely identifies the sub group.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label from which the sub group will be removed from the portfolio group.")] = None, async_req: Optional[bool]=True, **kwargs) -> PortfolioGroup:  # noqa: E501
        ...

    @validate_arguments
    def delete_sub_group_from_group(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group to remove the sub group from.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group to remove the sub group from. Together with the scope this uniquely identifies the portfolio group.")], subgroup_scope : Annotated[StrictStr, Field(..., description="The scope of the sub group to remove from the portfolio group.")], subgroup_code : Annotated[StrictStr, Field(..., description="The code of the sub group to remove from the portfolio group. Together with the scope this uniquely identifies the sub group.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label from which the sub group will be removed from the portfolio group.")] = None, async_req: Optional[bool]=None, **kwargs) -> Union[PortfolioGroup, Awaitable[PortfolioGroup]]:  # noqa: E501
        """[EARLY ACCESS] DeleteSubGroupFromGroup: Delete sub group from group  # noqa: E501

        Remove a single portfolio group (sub group) from a portfolio group.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.delete_sub_group_from_group(scope, code, subgroup_scope, subgroup_code, effective_at, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the portfolio group to remove the sub group from. (required)
        :type scope: str
        :param code: The code of the portfolio group to remove the sub group from. Together with the scope this uniquely identifies the portfolio group. (required)
        :type code: str
        :param subgroup_scope: The scope of the sub group to remove from the portfolio group. (required)
        :type subgroup_scope: str
        :param subgroup_code: The code of the sub group to remove from the portfolio group. Together with the scope this uniquely identifies the sub group. (required)
        :type subgroup_code: str
        :param effective_at: The effective datetime or cut label from which the sub group will be removed from the portfolio group.
        :type effective_at: str
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: PortfolioGroup
        """
        kwargs['_return_http_data_only'] = True
        if '_preload_content' in kwargs:
            message = "Error! Please call the delete_sub_group_from_group_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data"  # noqa: E501
            raise ValueError(message)
        if async_req is not None:
            kwargs['async_req'] = async_req
        return self.delete_sub_group_from_group_with_http_info(scope, code, subgroup_scope, subgroup_code, effective_at, **kwargs)  # noqa: E501

    @validate_arguments
    def delete_sub_group_from_group_with_http_info(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group to remove the sub group from.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group to remove the sub group from. Together with the scope this uniquely identifies the portfolio group.")], subgroup_scope : Annotated[StrictStr, Field(..., description="The scope of the sub group to remove from the portfolio group.")], subgroup_code : Annotated[StrictStr, Field(..., description="The code of the sub group to remove from the portfolio group. Together with the scope this uniquely identifies the sub group.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label from which the sub group will be removed from the portfolio group.")] = None, **kwargs) -> ApiResponse:  # noqa: E501
        """[EARLY ACCESS] DeleteSubGroupFromGroup: Delete sub group from group  # noqa: E501

        Remove a single portfolio group (sub group) from a portfolio group.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.delete_sub_group_from_group_with_http_info(scope, code, subgroup_scope, subgroup_code, effective_at, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the portfolio group to remove the sub group from. (required)
        :type scope: str
        :param code: The code of the portfolio group to remove the sub group from. Together with the scope this uniquely identifies the portfolio group. (required)
        :type code: str
        :param subgroup_scope: The scope of the sub group to remove from the portfolio group. (required)
        :type subgroup_scope: str
        :param subgroup_code: The code of the sub group to remove from the portfolio group. Together with the scope this uniquely identifies the sub group. (required)
        :type subgroup_code: str
        :param effective_at: The effective datetime or cut label from which the sub group will be removed from the portfolio group.
        :type effective_at: str
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _preload_content: if False, the ApiResponse.data will
                                 be set to none and raw_data will store the
                                 HTTP response body without reading/decoding.
                                 Default is True.
        :type _preload_content: bool, optional
        :param _return_http_data_only: response data instead of ApiResponse
                                       object with status code, headers, etc
        :type _return_http_data_only: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the authentication
                              in the spec for a single request.
        :type _request_auth: dict, optional
        :type _content_type: string, optional: force content-type for the request
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: tuple(PortfolioGroup, status_code(int), headers(HTTPHeaderDict))
        """

        _params = locals()

        _all_params = [
            'scope',
            'code',
            'subgroup_scope',
            'subgroup_code',
            'effective_at'
        ]
        _all_params.extend(
            [
                'async_req',
                '_return_http_data_only',
                '_preload_content',
                '_request_timeout',
                '_request_auth',
                '_content_type',
                '_headers',
                'opts'
            ]
        )

        # validate the arguments
        for _key, _val in _params['kwargs'].items():
            if _key not in _all_params:
                raise ApiTypeError(
                    "Got an unexpected keyword argument '%s'"
                    " to method delete_sub_group_from_group" % _key
                )
            _params[_key] = _val
        del _params['kwargs']

        _collection_formats = {}

        # process the path parameters
        _path_params = {}
        if _params['scope']:
            _path_params['scope'] = _params['scope']

        if _params['code']:
            _path_params['code'] = _params['code']

        if _params['subgroup_scope']:
            _path_params['subgroupScope'] = _params['subgroup_scope']

        if _params['subgroup_code']:
            _path_params['subgroupCode'] = _params['subgroup_code']


        # process the query parameters
        _query_params = []
        if _params.get('effective_at') is not None:  # noqa: E501
            _query_params.append(('effectiveAt', _params['effective_at']))

        # process the header parameters
        _header_params = dict(_params.get('_headers', {}))
        # process the form parameters
        _form_params = []
        _files = {}
        # process the body parameter
        _body_params = None
        # set the HTTP header `Accept`
        _header_params['Accept'] = self.api_client.select_header_accept(
            ['text/plain', 'application/json', 'text/json'])  # noqa: E501

        # authentication setting
        _auth_settings = ['oauth2']  # noqa: E501

        _response_types_map = {
            '200': "PortfolioGroup",
            '400': "LusidValidationProblemDetails",
        }

        return self.api_client.call_api(
            '/api/portfoliogroups/{scope}/{code}/subgroups/{subgroupScope}/{subgroupCode}', 'DELETE',
            _path_params,
            _query_params,
            _header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            response_types_map=_response_types_map,
            auth_settings=_auth_settings,
            async_req=_params.get('async_req'),
            _return_http_data_only=_params.get('_return_http_data_only'),  # noqa: E501
            _preload_content=_params.get('_preload_content', True),
            _request_timeout=_params.get('_request_timeout'),
            opts=_params.get('opts'),
            collection_formats=_collection_formats,
            _request_auth=_params.get('_request_auth'))


    @overload
    async def get_a2_b_data_for_portfolio_group(self, scope : Annotated[StrictStr, Field(..., description="The scope of the group to retrieve the A2B report for.")], code : Annotated[StrictStr, Field(..., description="The code of the group to retrieve the A2B report for. Together with the scope this              uniquely identifies the portfolio group.")], from_effective_at : Annotated[StrictStr, Field(..., description="The lower bound effective datetime or cut label (inclusive) from which to retrieve the data.              There is no lower bound if this is not specified.")], to_effective_at : Annotated[StrictStr, Field(..., description="The upper bound effective datetime or cut label (inclusive) from which to retrieve the data.              There is no upper bound if this is not specified.")], as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to retrieve the portfolio. Defaults to return the latest version              of each transaction if not specified.")] = None, recipe_id_scope : Annotated[Optional[StrictStr], Field( description="The scope of the given recipeId")] = None, recipe_id_code : Annotated[Optional[StrictStr], Field( description="The code of the given recipeId")] = None, property_keys : Annotated[Optional[List[StrictStr]], Field(description="A list of property keys from the \"Instrument\" domain to decorate onto              the results. These take the format {domain}/{scope}/{code} e.g. \"Instrument/system/Name\".")] = None, filter : Annotated[Optional[StrictStr], Field( description="Expression to filter the result set.              Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.")] = None, **kwargs) -> VersionedResourceListOfA2BDataRecord:  # noqa: E501
        ...

    @overload
    def get_a2_b_data_for_portfolio_group(self, scope : Annotated[StrictStr, Field(..., description="The scope of the group to retrieve the A2B report for.")], code : Annotated[StrictStr, Field(..., description="The code of the group to retrieve the A2B report for. Together with the scope this              uniquely identifies the portfolio group.")], from_effective_at : Annotated[StrictStr, Field(..., description="The lower bound effective datetime or cut label (inclusive) from which to retrieve the data.              There is no lower bound if this is not specified.")], to_effective_at : Annotated[StrictStr, Field(..., description="The upper bound effective datetime or cut label (inclusive) from which to retrieve the data.              There is no upper bound if this is not specified.")], as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to retrieve the portfolio. Defaults to return the latest version              of each transaction if not specified.")] = None, recipe_id_scope : Annotated[Optional[StrictStr], Field( description="The scope of the given recipeId")] = None, recipe_id_code : Annotated[Optional[StrictStr], Field( description="The code of the given recipeId")] = None, property_keys : Annotated[Optional[List[StrictStr]], Field(description="A list of property keys from the \"Instrument\" domain to decorate onto              the results. These take the format {domain}/{scope}/{code} e.g. \"Instrument/system/Name\".")] = None, filter : Annotated[Optional[StrictStr], Field( description="Expression to filter the result set.              Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.")] = None, async_req: Optional[bool]=True, **kwargs) -> VersionedResourceListOfA2BDataRecord:  # noqa: E501
        ...

    @validate_arguments
    def get_a2_b_data_for_portfolio_group(self, scope : Annotated[StrictStr, Field(..., description="The scope of the group to retrieve the A2B report for.")], code : Annotated[StrictStr, Field(..., description="The code of the group to retrieve the A2B report for. Together with the scope this              uniquely identifies the portfolio group.")], from_effective_at : Annotated[StrictStr, Field(..., description="The lower bound effective datetime or cut label (inclusive) from which to retrieve the data.              There is no lower bound if this is not specified.")], to_effective_at : Annotated[StrictStr, Field(..., description="The upper bound effective datetime or cut label (inclusive) from which to retrieve the data.              There is no upper bound if this is not specified.")], as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to retrieve the portfolio. Defaults to return the latest version              of each transaction if not specified.")] = None, recipe_id_scope : Annotated[Optional[StrictStr], Field( description="The scope of the given recipeId")] = None, recipe_id_code : Annotated[Optional[StrictStr], Field( description="The code of the given recipeId")] = None, property_keys : Annotated[Optional[List[StrictStr]], Field(description="A list of property keys from the \"Instrument\" domain to decorate onto              the results. These take the format {domain}/{scope}/{code} e.g. \"Instrument/system/Name\".")] = None, filter : Annotated[Optional[StrictStr], Field( description="Expression to filter the result set.              Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.")] = None, async_req: Optional[bool]=None, **kwargs) -> Union[VersionedResourceListOfA2BDataRecord, Awaitable[VersionedResourceListOfA2BDataRecord]]:  # noqa: E501
        """[EARLY ACCESS] GetA2BDataForPortfolioGroup: Get A2B data for a Portfolio Group  # noqa: E501

        Get an A2B report for all Transaction Portfolios within the given portfolio group.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.get_a2_b_data_for_portfolio_group(scope, code, from_effective_at, to_effective_at, as_at, recipe_id_scope, recipe_id_code, property_keys, filter, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the group to retrieve the A2B report for. (required)
        :type scope: str
        :param code: The code of the group to retrieve the A2B report for. Together with the scope this              uniquely identifies the portfolio group. (required)
        :type code: str
        :param from_effective_at: The lower bound effective datetime or cut label (inclusive) from which to retrieve the data.              There is no lower bound if this is not specified. (required)
        :type from_effective_at: str
        :param to_effective_at: The upper bound effective datetime or cut label (inclusive) from which to retrieve the data.              There is no upper bound if this is not specified. (required)
        :type to_effective_at: str
        :param as_at: The asAt datetime at which to retrieve the portfolio. Defaults to return the latest version              of each transaction if not specified.
        :type as_at: datetime
        :param recipe_id_scope: The scope of the given recipeId
        :type recipe_id_scope: str
        :param recipe_id_code: The code of the given recipeId
        :type recipe_id_code: str
        :param property_keys: A list of property keys from the \"Instrument\" domain to decorate onto              the results. These take the format {domain}/{scope}/{code} e.g. \"Instrument/system/Name\".
        :type property_keys: List[str]
        :param filter: Expression to filter the result set.              Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.
        :type filter: str
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: VersionedResourceListOfA2BDataRecord
        """
        kwargs['_return_http_data_only'] = True
        if '_preload_content' in kwargs:
            message = "Error! Please call the get_a2_b_data_for_portfolio_group_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data"  # noqa: E501
            raise ValueError(message)
        if async_req is not None:
            kwargs['async_req'] = async_req
        return self.get_a2_b_data_for_portfolio_group_with_http_info(scope, code, from_effective_at, to_effective_at, as_at, recipe_id_scope, recipe_id_code, property_keys, filter, **kwargs)  # noqa: E501

    @validate_arguments
    def get_a2_b_data_for_portfolio_group_with_http_info(self, scope : Annotated[StrictStr, Field(..., description="The scope of the group to retrieve the A2B report for.")], code : Annotated[StrictStr, Field(..., description="The code of the group to retrieve the A2B report for. Together with the scope this              uniquely identifies the portfolio group.")], from_effective_at : Annotated[StrictStr, Field(..., description="The lower bound effective datetime or cut label (inclusive) from which to retrieve the data.              There is no lower bound if this is not specified.")], to_effective_at : Annotated[StrictStr, Field(..., description="The upper bound effective datetime or cut label (inclusive) from which to retrieve the data.              There is no upper bound if this is not specified.")], as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to retrieve the portfolio. Defaults to return the latest version              of each transaction if not specified.")] = None, recipe_id_scope : Annotated[Optional[StrictStr], Field( description="The scope of the given recipeId")] = None, recipe_id_code : Annotated[Optional[StrictStr], Field( description="The code of the given recipeId")] = None, property_keys : Annotated[Optional[List[StrictStr]], Field(description="A list of property keys from the \"Instrument\" domain to decorate onto              the results. These take the format {domain}/{scope}/{code} e.g. \"Instrument/system/Name\".")] = None, filter : Annotated[Optional[StrictStr], Field( description="Expression to filter the result set.              Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.")] = None, **kwargs) -> ApiResponse:  # noqa: E501
        """[EARLY ACCESS] GetA2BDataForPortfolioGroup: Get A2B data for a Portfolio Group  # noqa: E501

        Get an A2B report for all Transaction Portfolios within the given portfolio group.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.get_a2_b_data_for_portfolio_group_with_http_info(scope, code, from_effective_at, to_effective_at, as_at, recipe_id_scope, recipe_id_code, property_keys, filter, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the group to retrieve the A2B report for. (required)
        :type scope: str
        :param code: The code of the group to retrieve the A2B report for. Together with the scope this              uniquely identifies the portfolio group. (required)
        :type code: str
        :param from_effective_at: The lower bound effective datetime or cut label (inclusive) from which to retrieve the data.              There is no lower bound if this is not specified. (required)
        :type from_effective_at: str
        :param to_effective_at: The upper bound effective datetime or cut label (inclusive) from which to retrieve the data.              There is no upper bound if this is not specified. (required)
        :type to_effective_at: str
        :param as_at: The asAt datetime at which to retrieve the portfolio. Defaults to return the latest version              of each transaction if not specified.
        :type as_at: datetime
        :param recipe_id_scope: The scope of the given recipeId
        :type recipe_id_scope: str
        :param recipe_id_code: The code of the given recipeId
        :type recipe_id_code: str
        :param property_keys: A list of property keys from the \"Instrument\" domain to decorate onto              the results. These take the format {domain}/{scope}/{code} e.g. \"Instrument/system/Name\".
        :type property_keys: List[str]
        :param filter: Expression to filter the result set.              Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.
        :type filter: str
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _preload_content: if False, the ApiResponse.data will
                                 be set to none and raw_data will store the
                                 HTTP response body without reading/decoding.
                                 Default is True.
        :type _preload_content: bool, optional
        :param _return_http_data_only: response data instead of ApiResponse
                                       object with status code, headers, etc
        :type _return_http_data_only: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the authentication
                              in the spec for a single request.
        :type _request_auth: dict, optional
        :type _content_type: string, optional: force content-type for the request
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: tuple(VersionedResourceListOfA2BDataRecord, status_code(int), headers(HTTPHeaderDict))
        """

        _params = locals()

        _all_params = [
            'scope',
            'code',
            'from_effective_at',
            'to_effective_at',
            'as_at',
            'recipe_id_scope',
            'recipe_id_code',
            'property_keys',
            'filter'
        ]
        _all_params.extend(
            [
                'async_req',
                '_return_http_data_only',
                '_preload_content',
                '_request_timeout',
                '_request_auth',
                '_content_type',
                '_headers',
                'opts'
            ]
        )

        # validate the arguments
        for _key, _val in _params['kwargs'].items():
            if _key not in _all_params:
                raise ApiTypeError(
                    "Got an unexpected keyword argument '%s'"
                    " to method get_a2_b_data_for_portfolio_group" % _key
                )
            _params[_key] = _val
        del _params['kwargs']

        _collection_formats = {}

        # process the path parameters
        _path_params = {}
        if _params['scope']:
            _path_params['scope'] = _params['scope']

        if _params['code']:
            _path_params['code'] = _params['code']


        # process the query parameters
        _query_params = []
        if _params.get('from_effective_at') is not None:  # noqa: E501
            _query_params.append(('fromEffectiveAt', _params['from_effective_at']))

        if _params.get('to_effective_at') is not None:  # noqa: E501
            _query_params.append(('toEffectiveAt', _params['to_effective_at']))

        if _params.get('as_at') is not None:  # noqa: E501
            if isinstance(_params['as_at'], datetime):
                _query_params.append(('asAt', _params['as_at'].strftime(self.api_client.configuration.datetime_format)))
            else:
                _query_params.append(('asAt', _params['as_at']))

        if _params.get('recipe_id_scope') is not None:  # noqa: E501
            _query_params.append(('recipeIdScope', _params['recipe_id_scope']))

        if _params.get('recipe_id_code') is not None:  # noqa: E501
            _query_params.append(('recipeIdCode', _params['recipe_id_code']))

        if _params.get('property_keys') is not None:  # noqa: E501
            _query_params.append(('propertyKeys', _params['property_keys']))
            _collection_formats['propertyKeys'] = 'multi'

        if _params.get('filter') is not None:  # noqa: E501
            _query_params.append(('filter', _params['filter']))

        # process the header parameters
        _header_params = dict(_params.get('_headers', {}))
        # process the form parameters
        _form_params = []
        _files = {}
        # process the body parameter
        _body_params = None
        # set the HTTP header `Accept`
        _header_params['Accept'] = self.api_client.select_header_accept(
            ['text/plain', 'application/json', 'text/json'])  # noqa: E501

        # authentication setting
        _auth_settings = ['oauth2']  # noqa: E501

        _response_types_map = {
            '200': "VersionedResourceListOfA2BDataRecord",
            '400': "LusidValidationProblemDetails",
        }

        return self.api_client.call_api(
            '/api/portfoliogroups/{scope}/{code}/a2b', 'GET',
            _path_params,
            _query_params,
            _header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            response_types_map=_response_types_map,
            auth_settings=_auth_settings,
            async_req=_params.get('async_req'),
            _return_http_data_only=_params.get('_return_http_data_only'),  # noqa: E501
            _preload_content=_params.get('_preload_content', True),
            _request_timeout=_params.get('_request_timeout'),
            opts=_params.get('opts'),
            collection_formats=_collection_formats,
            _request_auth=_params.get('_request_auth'))


    @overload
    async def get_group_properties(self, scope : Annotated[StrictStr, Field(..., description="The scope of the group to list the properties for.")], code : Annotated[StrictStr, Field(..., description="The code of the group to list the properties for. Together with the scope this uniquely identifies the group.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective date time or cut label at which to list the group's properties. Defaults to the current LUSID system datetime if not specified.")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt date time at which to list the group's properties. Defaults to return the latest version of each property if not specified.")] = None, **kwargs) -> PortfolioGroupProperties:  # noqa: E501
        ...

    @overload
    def get_group_properties(self, scope : Annotated[StrictStr, Field(..., description="The scope of the group to list the properties for.")], code : Annotated[StrictStr, Field(..., description="The code of the group to list the properties for. Together with the scope this uniquely identifies the group.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective date time or cut label at which to list the group's properties. Defaults to the current LUSID system datetime if not specified.")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt date time at which to list the group's properties. Defaults to return the latest version of each property if not specified.")] = None, async_req: Optional[bool]=True, **kwargs) -> PortfolioGroupProperties:  # noqa: E501
        ...

    @validate_arguments
    def get_group_properties(self, scope : Annotated[StrictStr, Field(..., description="The scope of the group to list the properties for.")], code : Annotated[StrictStr, Field(..., description="The code of the group to list the properties for. Together with the scope this uniquely identifies the group.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective date time or cut label at which to list the group's properties. Defaults to the current LUSID system datetime if not specified.")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt date time at which to list the group's properties. Defaults to return the latest version of each property if not specified.")] = None, async_req: Optional[bool]=None, **kwargs) -> Union[PortfolioGroupProperties, Awaitable[PortfolioGroupProperties]]:  # noqa: E501
        """[EARLY ACCESS] GetGroupProperties: Get group properties  # noqa: E501

        List all the properties of a single portfolio group.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.get_group_properties(scope, code, effective_at, as_at, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the group to list the properties for. (required)
        :type scope: str
        :param code: The code of the group to list the properties for. Together with the scope this uniquely identifies the group. (required)
        :type code: str
        :param effective_at: The effective date time or cut label at which to list the group's properties. Defaults to the current LUSID system datetime if not specified.
        :type effective_at: str
        :param as_at: The asAt date time at which to list the group's properties. Defaults to return the latest version of each property if not specified.
        :type as_at: datetime
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: PortfolioGroupProperties
        """
        kwargs['_return_http_data_only'] = True
        if '_preload_content' in kwargs:
            message = "Error! Please call the get_group_properties_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data"  # noqa: E501
            raise ValueError(message)
        if async_req is not None:
            kwargs['async_req'] = async_req
        return self.get_group_properties_with_http_info(scope, code, effective_at, as_at, **kwargs)  # noqa: E501

    @validate_arguments
    def get_group_properties_with_http_info(self, scope : Annotated[StrictStr, Field(..., description="The scope of the group to list the properties for.")], code : Annotated[StrictStr, Field(..., description="The code of the group to list the properties for. Together with the scope this uniquely identifies the group.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective date time or cut label at which to list the group's properties. Defaults to the current LUSID system datetime if not specified.")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt date time at which to list the group's properties. Defaults to return the latest version of each property if not specified.")] = None, **kwargs) -> ApiResponse:  # noqa: E501
        """[EARLY ACCESS] GetGroupProperties: Get group properties  # noqa: E501

        List all the properties of a single portfolio group.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.get_group_properties_with_http_info(scope, code, effective_at, as_at, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the group to list the properties for. (required)
        :type scope: str
        :param code: The code of the group to list the properties for. Together with the scope this uniquely identifies the group. (required)
        :type code: str
        :param effective_at: The effective date time or cut label at which to list the group's properties. Defaults to the current LUSID system datetime if not specified.
        :type effective_at: str
        :param as_at: The asAt date time at which to list the group's properties. Defaults to return the latest version of each property if not specified.
        :type as_at: datetime
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _preload_content: if False, the ApiResponse.data will
                                 be set to none and raw_data will store the
                                 HTTP response body without reading/decoding.
                                 Default is True.
        :type _preload_content: bool, optional
        :param _return_http_data_only: response data instead of ApiResponse
                                       object with status code, headers, etc
        :type _return_http_data_only: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the authentication
                              in the spec for a single request.
        :type _request_auth: dict, optional
        :type _content_type: string, optional: force content-type for the request
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: tuple(PortfolioGroupProperties, status_code(int), headers(HTTPHeaderDict))
        """

        _params = locals()

        _all_params = [
            'scope',
            'code',
            'effective_at',
            'as_at'
        ]
        _all_params.extend(
            [
                'async_req',
                '_return_http_data_only',
                '_preload_content',
                '_request_timeout',
                '_request_auth',
                '_content_type',
                '_headers',
                'opts'
            ]
        )

        # validate the arguments
        for _key, _val in _params['kwargs'].items():
            if _key not in _all_params:
                raise ApiTypeError(
                    "Got an unexpected keyword argument '%s'"
                    " to method get_group_properties" % _key
                )
            _params[_key] = _val
        del _params['kwargs']

        _collection_formats = {}

        # process the path parameters
        _path_params = {}
        if _params['scope']:
            _path_params['scope'] = _params['scope']

        if _params['code']:
            _path_params['code'] = _params['code']


        # process the query parameters
        _query_params = []
        if _params.get('effective_at') is not None:  # noqa: E501
            _query_params.append(('effectiveAt', _params['effective_at']))

        if _params.get('as_at') is not None:  # noqa: E501
            if isinstance(_params['as_at'], datetime):
                _query_params.append(('asAt', _params['as_at'].strftime(self.api_client.configuration.datetime_format)))
            else:
                _query_params.append(('asAt', _params['as_at']))

        # process the header parameters
        _header_params = dict(_params.get('_headers', {}))
        # process the form parameters
        _form_params = []
        _files = {}
        # process the body parameter
        _body_params = None
        # set the HTTP header `Accept`
        _header_params['Accept'] = self.api_client.select_header_accept(
            ['text/plain', 'application/json', 'text/json'])  # noqa: E501

        # authentication setting
        _auth_settings = ['oauth2']  # noqa: E501

        _response_types_map = {
            '200': "PortfolioGroupProperties",
            '400': "LusidValidationProblemDetails",
        }

        return self.api_client.call_api(
            '/api/portfoliogroups/{scope}/{code}/properties', 'GET',
            _path_params,
            _query_params,
            _header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            response_types_map=_response_types_map,
            auth_settings=_auth_settings,
            async_req=_params.get('async_req'),
            _return_http_data_only=_params.get('_return_http_data_only'),  # noqa: E501
            _preload_content=_params.get('_preload_content', True),
            _request_timeout=_params.get('_request_timeout'),
            opts=_params.get('opts'),
            collection_formats=_collection_formats,
            _request_auth=_params.get('_request_auth'))


    @overload
    async def get_holdings_for_portfolio_group(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group. Together with the scope this uniquely identifies              the portfolio group.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label at which to retrieve the holdings of transaction              portfolios in the portfolio group. Defaults to the current LUSID system datetime if not specified.")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to retrieve the holdings of transaction portfolios in the portfolio group. Defaults              to return the latest version of the holdings if not specified.")] = None, filter : Annotated[Optional[StrictStr], Field( description="Expression to filter the result set. Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.")] = None, property_keys : Annotated[Optional[List[StrictStr]], Field(description="A list of property keys from the \"Instrument\", \"Holding\" or \"Portfolio\" domain to decorate onto              the holdings. These take the format {domain}/{scope}/{code} e.g. \"Instrument/system/Name\" or \"Holding/system/Cost\".")] = None, by_taxlots : Annotated[Optional[StrictBool], Field(description="Whether or not to expand the holdings to return the underlying tax-lots. Defaults to              False.")] = None, include_settlement_events_after_days : Annotated[Optional[StrictInt], Field(description="Number of days ahead to bring back settlements from, in relation to the specified effectiveAt")] = None, **kwargs) -> VersionedResourceListOfPortfolioHolding:  # noqa: E501
        ...

    @overload
    def get_holdings_for_portfolio_group(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group. Together with the scope this uniquely identifies              the portfolio group.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label at which to retrieve the holdings of transaction              portfolios in the portfolio group. Defaults to the current LUSID system datetime if not specified.")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to retrieve the holdings of transaction portfolios in the portfolio group. Defaults              to return the latest version of the holdings if not specified.")] = None, filter : Annotated[Optional[StrictStr], Field( description="Expression to filter the result set. Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.")] = None, property_keys : Annotated[Optional[List[StrictStr]], Field(description="A list of property keys from the \"Instrument\", \"Holding\" or \"Portfolio\" domain to decorate onto              the holdings. These take the format {domain}/{scope}/{code} e.g. \"Instrument/system/Name\" or \"Holding/system/Cost\".")] = None, by_taxlots : Annotated[Optional[StrictBool], Field(description="Whether or not to expand the holdings to return the underlying tax-lots. Defaults to              False.")] = None, include_settlement_events_after_days : Annotated[Optional[StrictInt], Field(description="Number of days ahead to bring back settlements from, in relation to the specified effectiveAt")] = None, async_req: Optional[bool]=True, **kwargs) -> VersionedResourceListOfPortfolioHolding:  # noqa: E501
        ...

    @validate_arguments
    def get_holdings_for_portfolio_group(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group. Together with the scope this uniquely identifies              the portfolio group.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label at which to retrieve the holdings of transaction              portfolios in the portfolio group. Defaults to the current LUSID system datetime if not specified.")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to retrieve the holdings of transaction portfolios in the portfolio group. Defaults              to return the latest version of the holdings if not specified.")] = None, filter : Annotated[Optional[StrictStr], Field( description="Expression to filter the result set. Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.")] = None, property_keys : Annotated[Optional[List[StrictStr]], Field(description="A list of property keys from the \"Instrument\", \"Holding\" or \"Portfolio\" domain to decorate onto              the holdings. These take the format {domain}/{scope}/{code} e.g. \"Instrument/system/Name\" or \"Holding/system/Cost\".")] = None, by_taxlots : Annotated[Optional[StrictBool], Field(description="Whether or not to expand the holdings to return the underlying tax-lots. Defaults to              False.")] = None, include_settlement_events_after_days : Annotated[Optional[StrictInt], Field(description="Number of days ahead to bring back settlements from, in relation to the specified effectiveAt")] = None, async_req: Optional[bool]=None, **kwargs) -> Union[VersionedResourceListOfPortfolioHolding, Awaitable[VersionedResourceListOfPortfolioHolding]]:  # noqa: E501
        """GetHoldingsForPortfolioGroup: Get holdings for transaction portfolios in portfolio group  # noqa: E501

        Get the holdings of transaction portfolios in specified portfolio group.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.get_holdings_for_portfolio_group(scope, code, effective_at, as_at, filter, property_keys, by_taxlots, include_settlement_events_after_days, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the portfolio group. (required)
        :type scope: str
        :param code: The code of the portfolio group. Together with the scope this uniquely identifies              the portfolio group. (required)
        :type code: str
        :param effective_at: The effective datetime or cut label at which to retrieve the holdings of transaction              portfolios in the portfolio group. Defaults to the current LUSID system datetime if not specified.
        :type effective_at: str
        :param as_at: The asAt datetime at which to retrieve the holdings of transaction portfolios in the portfolio group. Defaults              to return the latest version of the holdings if not specified.
        :type as_at: datetime
        :param filter: Expression to filter the result set. Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.
        :type filter: str
        :param property_keys: A list of property keys from the \"Instrument\", \"Holding\" or \"Portfolio\" domain to decorate onto              the holdings. These take the format {domain}/{scope}/{code} e.g. \"Instrument/system/Name\" or \"Holding/system/Cost\".
        :type property_keys: List[str]
        :param by_taxlots: Whether or not to expand the holdings to return the underlying tax-lots. Defaults to              False.
        :type by_taxlots: bool
        :param include_settlement_events_after_days: Number of days ahead to bring back settlements from, in relation to the specified effectiveAt
        :type include_settlement_events_after_days: int
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: VersionedResourceListOfPortfolioHolding
        """
        kwargs['_return_http_data_only'] = True
        if '_preload_content' in kwargs:
            message = "Error! Please call the get_holdings_for_portfolio_group_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data"  # noqa: E501
            raise ValueError(message)
        if async_req is not None:
            kwargs['async_req'] = async_req
        return self.get_holdings_for_portfolio_group_with_http_info(scope, code, effective_at, as_at, filter, property_keys, by_taxlots, include_settlement_events_after_days, **kwargs)  # noqa: E501

    @validate_arguments
    def get_holdings_for_portfolio_group_with_http_info(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group. Together with the scope this uniquely identifies              the portfolio group.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label at which to retrieve the holdings of transaction              portfolios in the portfolio group. Defaults to the current LUSID system datetime if not specified.")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to retrieve the holdings of transaction portfolios in the portfolio group. Defaults              to return the latest version of the holdings if not specified.")] = None, filter : Annotated[Optional[StrictStr], Field( description="Expression to filter the result set. Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.")] = None, property_keys : Annotated[Optional[List[StrictStr]], Field(description="A list of property keys from the \"Instrument\", \"Holding\" or \"Portfolio\" domain to decorate onto              the holdings. These take the format {domain}/{scope}/{code} e.g. \"Instrument/system/Name\" or \"Holding/system/Cost\".")] = None, by_taxlots : Annotated[Optional[StrictBool], Field(description="Whether or not to expand the holdings to return the underlying tax-lots. Defaults to              False.")] = None, include_settlement_events_after_days : Annotated[Optional[StrictInt], Field(description="Number of days ahead to bring back settlements from, in relation to the specified effectiveAt")] = None, **kwargs) -> ApiResponse:  # noqa: E501
        """GetHoldingsForPortfolioGroup: Get holdings for transaction portfolios in portfolio group  # noqa: E501

        Get the holdings of transaction portfolios in specified portfolio group.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.get_holdings_for_portfolio_group_with_http_info(scope, code, effective_at, as_at, filter, property_keys, by_taxlots, include_settlement_events_after_days, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the portfolio group. (required)
        :type scope: str
        :param code: The code of the portfolio group. Together with the scope this uniquely identifies              the portfolio group. (required)
        :type code: str
        :param effective_at: The effective datetime or cut label at which to retrieve the holdings of transaction              portfolios in the portfolio group. Defaults to the current LUSID system datetime if not specified.
        :type effective_at: str
        :param as_at: The asAt datetime at which to retrieve the holdings of transaction portfolios in the portfolio group. Defaults              to return the latest version of the holdings if not specified.
        :type as_at: datetime
        :param filter: Expression to filter the result set. Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.
        :type filter: str
        :param property_keys: A list of property keys from the \"Instrument\", \"Holding\" or \"Portfolio\" domain to decorate onto              the holdings. These take the format {domain}/{scope}/{code} e.g. \"Instrument/system/Name\" or \"Holding/system/Cost\".
        :type property_keys: List[str]
        :param by_taxlots: Whether or not to expand the holdings to return the underlying tax-lots. Defaults to              False.
        :type by_taxlots: bool
        :param include_settlement_events_after_days: Number of days ahead to bring back settlements from, in relation to the specified effectiveAt
        :type include_settlement_events_after_days: int
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _preload_content: if False, the ApiResponse.data will
                                 be set to none and raw_data will store the
                                 HTTP response body without reading/decoding.
                                 Default is True.
        :type _preload_content: bool, optional
        :param _return_http_data_only: response data instead of ApiResponse
                                       object with status code, headers, etc
        :type _return_http_data_only: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the authentication
                              in the spec for a single request.
        :type _request_auth: dict, optional
        :type _content_type: string, optional: force content-type for the request
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: tuple(VersionedResourceListOfPortfolioHolding, status_code(int), headers(HTTPHeaderDict))
        """

        _params = locals()

        _all_params = [
            'scope',
            'code',
            'effective_at',
            'as_at',
            'filter',
            'property_keys',
            'by_taxlots',
            'include_settlement_events_after_days'
        ]
        _all_params.extend(
            [
                'async_req',
                '_return_http_data_only',
                '_preload_content',
                '_request_timeout',
                '_request_auth',
                '_content_type',
                '_headers',
                'opts'
            ]
        )

        # validate the arguments
        for _key, _val in _params['kwargs'].items():
            if _key not in _all_params:
                raise ApiTypeError(
                    "Got an unexpected keyword argument '%s'"
                    " to method get_holdings_for_portfolio_group" % _key
                )
            _params[_key] = _val
        del _params['kwargs']

        _collection_formats = {}

        # process the path parameters
        _path_params = {}
        if _params['scope']:
            _path_params['scope'] = _params['scope']

        if _params['code']:
            _path_params['code'] = _params['code']


        # process the query parameters
        _query_params = []
        if _params.get('effective_at') is not None:  # noqa: E501
            _query_params.append(('effectiveAt', _params['effective_at']))

        if _params.get('as_at') is not None:  # noqa: E501
            if isinstance(_params['as_at'], datetime):
                _query_params.append(('asAt', _params['as_at'].strftime(self.api_client.configuration.datetime_format)))
            else:
                _query_params.append(('asAt', _params['as_at']))

        if _params.get('filter') is not None:  # noqa: E501
            _query_params.append(('filter', _params['filter']))

        if _params.get('property_keys') is not None:  # noqa: E501
            _query_params.append(('propertyKeys', _params['property_keys']))
            _collection_formats['propertyKeys'] = 'multi'

        if _params.get('by_taxlots') is not None:  # noqa: E501
            _query_params.append(('byTaxlots', _params['by_taxlots']))

        if _params.get('include_settlement_events_after_days') is not None:  # noqa: E501
            _query_params.append(('includeSettlementEventsAfterDays', _params['include_settlement_events_after_days']))

        # process the header parameters
        _header_params = dict(_params.get('_headers', {}))
        # process the form parameters
        _form_params = []
        _files = {}
        # process the body parameter
        _body_params = None
        # set the HTTP header `Accept`
        _header_params['Accept'] = self.api_client.select_header_accept(
            ['text/plain', 'application/json', 'text/json'])  # noqa: E501

        # authentication setting
        _auth_settings = ['oauth2']  # noqa: E501

        _response_types_map = {
            '200': "VersionedResourceListOfPortfolioHolding",
            '400': "LusidValidationProblemDetails",
        }

        return self.api_client.call_api(
            '/api/portfoliogroups/{scope}/{code}/holdings', 'GET',
            _path_params,
            _query_params,
            _header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            response_types_map=_response_types_map,
            auth_settings=_auth_settings,
            async_req=_params.get('async_req'),
            _return_http_data_only=_params.get('_return_http_data_only'),  # noqa: E501
            _preload_content=_params.get('_preload_content', True),
            _request_timeout=_params.get('_request_timeout'),
            opts=_params.get('opts'),
            collection_formats=_collection_formats,
            _request_auth=_params.get('_request_auth'))


    @overload
    async def get_portfolio_group(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group to retrieve the definition for.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group to retrieve the definition for. Together with the scope              this uniquely identifies the portfolio group.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label at which to retrieve the portfolio group definition. Defaults to the current LUSID system datetime if not specified.")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to retrieve the portfolio group definition. Defaults to return              the latest version of the portfolio group definition if not specified.")] = None, related_entity_property_keys : Annotated[Optional[List[StrictStr]], Field(description="A list of property keys from any domain that supports relationships              to decorate onto related entities. These must take the format {domain}/{scope}/{code}, for example 'Portfolio/Manager/Id'.")] = None, relationship_definition_ids : Annotated[Optional[List[StrictStr]], Field(description="A list of relationship definitions that are used to decorate related entities              onto the portfolio group in the response. These must take the form {relationshipDefinitionScope}/{relationshipDefinitionCode}.")] = None, **kwargs) -> PortfolioGroup:  # noqa: E501
        ...

    @overload
    def get_portfolio_group(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group to retrieve the definition for.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group to retrieve the definition for. Together with the scope              this uniquely identifies the portfolio group.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label at which to retrieve the portfolio group definition. Defaults to the current LUSID system datetime if not specified.")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to retrieve the portfolio group definition. Defaults to return              the latest version of the portfolio group definition if not specified.")] = None, related_entity_property_keys : Annotated[Optional[List[StrictStr]], Field(description="A list of property keys from any domain that supports relationships              to decorate onto related entities. These must take the format {domain}/{scope}/{code}, for example 'Portfolio/Manager/Id'.")] = None, relationship_definition_ids : Annotated[Optional[List[StrictStr]], Field(description="A list of relationship definitions that are used to decorate related entities              onto the portfolio group in the response. These must take the form {relationshipDefinitionScope}/{relationshipDefinitionCode}.")] = None, async_req: Optional[bool]=True, **kwargs) -> PortfolioGroup:  # noqa: E501
        ...

    @validate_arguments
    def get_portfolio_group(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group to retrieve the definition for.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group to retrieve the definition for. Together with the scope              this uniquely identifies the portfolio group.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label at which to retrieve the portfolio group definition. Defaults to the current LUSID system datetime if not specified.")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to retrieve the portfolio group definition. Defaults to return              the latest version of the portfolio group definition if not specified.")] = None, related_entity_property_keys : Annotated[Optional[List[StrictStr]], Field(description="A list of property keys from any domain that supports relationships              to decorate onto related entities. These must take the format {domain}/{scope}/{code}, for example 'Portfolio/Manager/Id'.")] = None, relationship_definition_ids : Annotated[Optional[List[StrictStr]], Field(description="A list of relationship definitions that are used to decorate related entities              onto the portfolio group in the response. These must take the form {relationshipDefinitionScope}/{relationshipDefinitionCode}.")] = None, async_req: Optional[bool]=None, **kwargs) -> Union[PortfolioGroup, Awaitable[PortfolioGroup]]:  # noqa: E501
        """GetPortfolioGroup: Get portfolio group  # noqa: E501

        Retrieve the definition of a single portfolio group.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.get_portfolio_group(scope, code, effective_at, as_at, related_entity_property_keys, relationship_definition_ids, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the portfolio group to retrieve the definition for. (required)
        :type scope: str
        :param code: The code of the portfolio group to retrieve the definition for. Together with the scope              this uniquely identifies the portfolio group. (required)
        :type code: str
        :param effective_at: The effective datetime or cut label at which to retrieve the portfolio group definition. Defaults to the current LUSID system datetime if not specified.
        :type effective_at: str
        :param as_at: The asAt datetime at which to retrieve the portfolio group definition. Defaults to return              the latest version of the portfolio group definition if not specified.
        :type as_at: datetime
        :param related_entity_property_keys: A list of property keys from any domain that supports relationships              to decorate onto related entities. These must take the format {domain}/{scope}/{code}, for example 'Portfolio/Manager/Id'.
        :type related_entity_property_keys: List[str]
        :param relationship_definition_ids: A list of relationship definitions that are used to decorate related entities              onto the portfolio group in the response. These must take the form {relationshipDefinitionScope}/{relationshipDefinitionCode}.
        :type relationship_definition_ids: List[str]
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: PortfolioGroup
        """
        kwargs['_return_http_data_only'] = True
        if '_preload_content' in kwargs:
            message = "Error! Please call the get_portfolio_group_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data"  # noqa: E501
            raise ValueError(message)
        if async_req is not None:
            kwargs['async_req'] = async_req
        return self.get_portfolio_group_with_http_info(scope, code, effective_at, as_at, related_entity_property_keys, relationship_definition_ids, **kwargs)  # noqa: E501

    @validate_arguments
    def get_portfolio_group_with_http_info(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group to retrieve the definition for.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group to retrieve the definition for. Together with the scope              this uniquely identifies the portfolio group.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label at which to retrieve the portfolio group definition. Defaults to the current LUSID system datetime if not specified.")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to retrieve the portfolio group definition. Defaults to return              the latest version of the portfolio group definition if not specified.")] = None, related_entity_property_keys : Annotated[Optional[List[StrictStr]], Field(description="A list of property keys from any domain that supports relationships              to decorate onto related entities. These must take the format {domain}/{scope}/{code}, for example 'Portfolio/Manager/Id'.")] = None, relationship_definition_ids : Annotated[Optional[List[StrictStr]], Field(description="A list of relationship definitions that are used to decorate related entities              onto the portfolio group in the response. These must take the form {relationshipDefinitionScope}/{relationshipDefinitionCode}.")] = None, **kwargs) -> ApiResponse:  # noqa: E501
        """GetPortfolioGroup: Get portfolio group  # noqa: E501

        Retrieve the definition of a single portfolio group.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.get_portfolio_group_with_http_info(scope, code, effective_at, as_at, related_entity_property_keys, relationship_definition_ids, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the portfolio group to retrieve the definition for. (required)
        :type scope: str
        :param code: The code of the portfolio group to retrieve the definition for. Together with the scope              this uniquely identifies the portfolio group. (required)
        :type code: str
        :param effective_at: The effective datetime or cut label at which to retrieve the portfolio group definition. Defaults to the current LUSID system datetime if not specified.
        :type effective_at: str
        :param as_at: The asAt datetime at which to retrieve the portfolio group definition. Defaults to return              the latest version of the portfolio group definition if not specified.
        :type as_at: datetime
        :param related_entity_property_keys: A list of property keys from any domain that supports relationships              to decorate onto related entities. These must take the format {domain}/{scope}/{code}, for example 'Portfolio/Manager/Id'.
        :type related_entity_property_keys: List[str]
        :param relationship_definition_ids: A list of relationship definitions that are used to decorate related entities              onto the portfolio group in the response. These must take the form {relationshipDefinitionScope}/{relationshipDefinitionCode}.
        :type relationship_definition_ids: List[str]
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _preload_content: if False, the ApiResponse.data will
                                 be set to none and raw_data will store the
                                 HTTP response body without reading/decoding.
                                 Default is True.
        :type _preload_content: bool, optional
        :param _return_http_data_only: response data instead of ApiResponse
                                       object with status code, headers, etc
        :type _return_http_data_only: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the authentication
                              in the spec for a single request.
        :type _request_auth: dict, optional
        :type _content_type: string, optional: force content-type for the request
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: tuple(PortfolioGroup, status_code(int), headers(HTTPHeaderDict))
        """

        _params = locals()

        _all_params = [
            'scope',
            'code',
            'effective_at',
            'as_at',
            'related_entity_property_keys',
            'relationship_definition_ids'
        ]
        _all_params.extend(
            [
                'async_req',
                '_return_http_data_only',
                '_preload_content',
                '_request_timeout',
                '_request_auth',
                '_content_type',
                '_headers',
                'opts'
            ]
        )

        # validate the arguments
        for _key, _val in _params['kwargs'].items():
            if _key not in _all_params:
                raise ApiTypeError(
                    "Got an unexpected keyword argument '%s'"
                    " to method get_portfolio_group" % _key
                )
            _params[_key] = _val
        del _params['kwargs']

        _collection_formats = {}

        # process the path parameters
        _path_params = {}
        if _params['scope']:
            _path_params['scope'] = _params['scope']

        if _params['code']:
            _path_params['code'] = _params['code']


        # process the query parameters
        _query_params = []
        if _params.get('effective_at') is not None:  # noqa: E501
            _query_params.append(('effectiveAt', _params['effective_at']))

        if _params.get('as_at') is not None:  # noqa: E501
            if isinstance(_params['as_at'], datetime):
                _query_params.append(('asAt', _params['as_at'].strftime(self.api_client.configuration.datetime_format)))
            else:
                _query_params.append(('asAt', _params['as_at']))

        if _params.get('related_entity_property_keys') is not None:  # noqa: E501
            _query_params.append(('relatedEntityPropertyKeys', _params['related_entity_property_keys']))
            _collection_formats['relatedEntityPropertyKeys'] = 'multi'

        if _params.get('relationship_definition_ids') is not None:  # noqa: E501
            _query_params.append(('relationshipDefinitionIds', _params['relationship_definition_ids']))
            _collection_formats['relationshipDefinitionIds'] = 'multi'

        # process the header parameters
        _header_params = dict(_params.get('_headers', {}))
        # process the form parameters
        _form_params = []
        _files = {}
        # process the body parameter
        _body_params = None
        # set the HTTP header `Accept`
        _header_params['Accept'] = self.api_client.select_header_accept(
            ['text/plain', 'application/json', 'text/json'])  # noqa: E501

        # authentication setting
        _auth_settings = ['oauth2']  # noqa: E501

        _response_types_map = {
            '200': "PortfolioGroup",
            '400': "LusidValidationProblemDetails",
        }

        return self.api_client.call_api(
            '/api/portfoliogroups/{scope}/{code}', 'GET',
            _path_params,
            _query_params,
            _header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            response_types_map=_response_types_map,
            auth_settings=_auth_settings,
            async_req=_params.get('async_req'),
            _return_http_data_only=_params.get('_return_http_data_only'),  # noqa: E501
            _preload_content=_params.get('_preload_content', True),
            _request_timeout=_params.get('_request_timeout'),
            opts=_params.get('opts'),
            collection_formats=_collection_formats,
            _request_auth=_params.get('_request_auth'))


    @overload
    async def get_portfolio_group_access_metadata_by_key(self, scope : Annotated[StrictStr, Field(..., description="The scope of the Portfolio Group")], code : Annotated[StrictStr, Field(..., description="The Portfolio Group code")], metadata_key : Annotated[StrictStr, Field(..., description="Key of the metadata entry to retrieve")], effective_at : Annotated[Optional[StrictStr], Field( description="The effectiveAt datetime at which to retrieve the access metadata")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to retrieve the access metadata")] = None, **kwargs) -> List[AccessMetadataValue]:  # noqa: E501
        ...

    @overload
    def get_portfolio_group_access_metadata_by_key(self, scope : Annotated[StrictStr, Field(..., description="The scope of the Portfolio Group")], code : Annotated[StrictStr, Field(..., description="The Portfolio Group code")], metadata_key : Annotated[StrictStr, Field(..., description="Key of the metadata entry to retrieve")], effective_at : Annotated[Optional[StrictStr], Field( description="The effectiveAt datetime at which to retrieve the access metadata")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to retrieve the access metadata")] = None, async_req: Optional[bool]=True, **kwargs) -> List[AccessMetadataValue]:  # noqa: E501
        ...

    @validate_arguments
    def get_portfolio_group_access_metadata_by_key(self, scope : Annotated[StrictStr, Field(..., description="The scope of the Portfolio Group")], code : Annotated[StrictStr, Field(..., description="The Portfolio Group code")], metadata_key : Annotated[StrictStr, Field(..., description="Key of the metadata entry to retrieve")], effective_at : Annotated[Optional[StrictStr], Field( description="The effectiveAt datetime at which to retrieve the access metadata")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to retrieve the access metadata")] = None, async_req: Optional[bool]=None, **kwargs) -> Union[List[AccessMetadataValue], Awaitable[List[AccessMetadataValue]]]:  # noqa: E501
        """[EARLY ACCESS] GetPortfolioGroupAccessMetadataByKey: Get an entry identified by a metadataKey in the Access Metadata of a Portfolio Group  # noqa: E501

        Get a specific Portfolio Group access metadata by specifying the corresponding identifier parts                No matching will be performed through this endpoint. To retrieve a rule, it is necessary to specify, exactly, the identifier of the rule  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.get_portfolio_group_access_metadata_by_key(scope, code, metadata_key, effective_at, as_at, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the Portfolio Group (required)
        :type scope: str
        :param code: The Portfolio Group code (required)
        :type code: str
        :param metadata_key: Key of the metadata entry to retrieve (required)
        :type metadata_key: str
        :param effective_at: The effectiveAt datetime at which to retrieve the access metadata
        :type effective_at: str
        :param as_at: The asAt datetime at which to retrieve the access metadata
        :type as_at: datetime
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: List[AccessMetadataValue]
        """
        kwargs['_return_http_data_only'] = True
        if '_preload_content' in kwargs:
            message = "Error! Please call the get_portfolio_group_access_metadata_by_key_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data"  # noqa: E501
            raise ValueError(message)
        if async_req is not None:
            kwargs['async_req'] = async_req
        return self.get_portfolio_group_access_metadata_by_key_with_http_info(scope, code, metadata_key, effective_at, as_at, **kwargs)  # noqa: E501

    @validate_arguments
    def get_portfolio_group_access_metadata_by_key_with_http_info(self, scope : Annotated[StrictStr, Field(..., description="The scope of the Portfolio Group")], code : Annotated[StrictStr, Field(..., description="The Portfolio Group code")], metadata_key : Annotated[StrictStr, Field(..., description="Key of the metadata entry to retrieve")], effective_at : Annotated[Optional[StrictStr], Field( description="The effectiveAt datetime at which to retrieve the access metadata")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to retrieve the access metadata")] = None, **kwargs) -> ApiResponse:  # noqa: E501
        """[EARLY ACCESS] GetPortfolioGroupAccessMetadataByKey: Get an entry identified by a metadataKey in the Access Metadata of a Portfolio Group  # noqa: E501

        Get a specific Portfolio Group access metadata by specifying the corresponding identifier parts                No matching will be performed through this endpoint. To retrieve a rule, it is necessary to specify, exactly, the identifier of the rule  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.get_portfolio_group_access_metadata_by_key_with_http_info(scope, code, metadata_key, effective_at, as_at, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the Portfolio Group (required)
        :type scope: str
        :param code: The Portfolio Group code (required)
        :type code: str
        :param metadata_key: Key of the metadata entry to retrieve (required)
        :type metadata_key: str
        :param effective_at: The effectiveAt datetime at which to retrieve the access metadata
        :type effective_at: str
        :param as_at: The asAt datetime at which to retrieve the access metadata
        :type as_at: datetime
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _preload_content: if False, the ApiResponse.data will
                                 be set to none and raw_data will store the
                                 HTTP response body without reading/decoding.
                                 Default is True.
        :type _preload_content: bool, optional
        :param _return_http_data_only: response data instead of ApiResponse
                                       object with status code, headers, etc
        :type _return_http_data_only: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the authentication
                              in the spec for a single request.
        :type _request_auth: dict, optional
        :type _content_type: string, optional: force content-type for the request
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: tuple(List[AccessMetadataValue], status_code(int), headers(HTTPHeaderDict))
        """

        _params = locals()

        _all_params = [
            'scope',
            'code',
            'metadata_key',
            'effective_at',
            'as_at'
        ]
        _all_params.extend(
            [
                'async_req',
                '_return_http_data_only',
                '_preload_content',
                '_request_timeout',
                '_request_auth',
                '_content_type',
                '_headers',
                'opts'
            ]
        )

        # validate the arguments
        for _key, _val in _params['kwargs'].items():
            if _key not in _all_params:
                raise ApiTypeError(
                    "Got an unexpected keyword argument '%s'"
                    " to method get_portfolio_group_access_metadata_by_key" % _key
                )
            _params[_key] = _val
        del _params['kwargs']

        _collection_formats = {}

        # process the path parameters
        _path_params = {}
        if _params['scope']:
            _path_params['scope'] = _params['scope']

        if _params['code']:
            _path_params['code'] = _params['code']

        if _params['metadata_key']:
            _path_params['metadataKey'] = _params['metadata_key']


        # process the query parameters
        _query_params = []
        if _params.get('effective_at') is not None:  # noqa: E501
            _query_params.append(('effectiveAt', _params['effective_at']))

        if _params.get('as_at') is not None:  # noqa: E501
            if isinstance(_params['as_at'], datetime):
                _query_params.append(('asAt', _params['as_at'].strftime(self.api_client.configuration.datetime_format)))
            else:
                _query_params.append(('asAt', _params['as_at']))

        # process the header parameters
        _header_params = dict(_params.get('_headers', {}))
        # process the form parameters
        _form_params = []
        _files = {}
        # process the body parameter
        _body_params = None
        # set the HTTP header `Accept`
        _header_params['Accept'] = self.api_client.select_header_accept(
            ['text/plain', 'application/json', 'text/json'])  # noqa: E501

        # authentication setting
        _auth_settings = ['oauth2']  # noqa: E501

        _response_types_map = {
            '200': "List[AccessMetadataValue]",
            '400': "LusidValidationProblemDetails",
        }

        return self.api_client.call_api(
            '/api/portfoliogroups/{scope}/{code}/metadata/{metadataKey}', 'GET',
            _path_params,
            _query_params,
            _header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            response_types_map=_response_types_map,
            auth_settings=_auth_settings,
            async_req=_params.get('async_req'),
            _return_http_data_only=_params.get('_return_http_data_only'),  # noqa: E501
            _preload_content=_params.get('_preload_content', True),
            _request_timeout=_params.get('_request_timeout'),
            opts=_params.get('opts'),
            collection_formats=_collection_formats,
            _request_auth=_params.get('_request_auth'))


    @overload
    async def get_portfolio_group_commands(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group to retrieve the commands for.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group to retrieve the commands for. Together with the scope this uniquely identifies the portfolio group.")], from_as_at : Annotated[Optional[datetime], Field(description="The lower bound asAt datetime (inclusive) from which to retrieve commands. There is no lower bound if this is not specified.")] = None, to_as_at : Annotated[Optional[datetime], Field(description="The upper bound asAt datetime (inclusive) from which to retrieve commands. There is no upper bound if this is not specified.")] = None, filter : Annotated[Optional[StrictStr], Field( description="Expression to filter the result set.               For example, to filter on the User ID, use \"userId.id eq 'string'\"              Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.")] = None, **kwargs) -> ResourceListOfProcessedCommand:  # noqa: E501
        ...

    @overload
    def get_portfolio_group_commands(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group to retrieve the commands for.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group to retrieve the commands for. Together with the scope this uniquely identifies the portfolio group.")], from_as_at : Annotated[Optional[datetime], Field(description="The lower bound asAt datetime (inclusive) from which to retrieve commands. There is no lower bound if this is not specified.")] = None, to_as_at : Annotated[Optional[datetime], Field(description="The upper bound asAt datetime (inclusive) from which to retrieve commands. There is no upper bound if this is not specified.")] = None, filter : Annotated[Optional[StrictStr], Field( description="Expression to filter the result set.               For example, to filter on the User ID, use \"userId.id eq 'string'\"              Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.")] = None, async_req: Optional[bool]=True, **kwargs) -> ResourceListOfProcessedCommand:  # noqa: E501
        ...

    @validate_arguments
    def get_portfolio_group_commands(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group to retrieve the commands for.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group to retrieve the commands for. Together with the scope this uniquely identifies the portfolio group.")], from_as_at : Annotated[Optional[datetime], Field(description="The lower bound asAt datetime (inclusive) from which to retrieve commands. There is no lower bound if this is not specified.")] = None, to_as_at : Annotated[Optional[datetime], Field(description="The upper bound asAt datetime (inclusive) from which to retrieve commands. There is no upper bound if this is not specified.")] = None, filter : Annotated[Optional[StrictStr], Field( description="Expression to filter the result set.               For example, to filter on the User ID, use \"userId.id eq 'string'\"              Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.")] = None, async_req: Optional[bool]=None, **kwargs) -> Union[ResourceListOfProcessedCommand, Awaitable[ResourceListOfProcessedCommand]]:  # noqa: E501
        """GetPortfolioGroupCommands: Get portfolio group commands  # noqa: E501

        Gets all the commands that modified a single portfolio group.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.get_portfolio_group_commands(scope, code, from_as_at, to_as_at, filter, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the portfolio group to retrieve the commands for. (required)
        :type scope: str
        :param code: The code of the portfolio group to retrieve the commands for. Together with the scope this uniquely identifies the portfolio group. (required)
        :type code: str
        :param from_as_at: The lower bound asAt datetime (inclusive) from which to retrieve commands. There is no lower bound if this is not specified.
        :type from_as_at: datetime
        :param to_as_at: The upper bound asAt datetime (inclusive) from which to retrieve commands. There is no upper bound if this is not specified.
        :type to_as_at: datetime
        :param filter: Expression to filter the result set.               For example, to filter on the User ID, use \"userId.id eq 'string'\"              Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.
        :type filter: str
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: ResourceListOfProcessedCommand
        """
        kwargs['_return_http_data_only'] = True
        if '_preload_content' in kwargs:
            message = "Error! Please call the get_portfolio_group_commands_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data"  # noqa: E501
            raise ValueError(message)
        if async_req is not None:
            kwargs['async_req'] = async_req
        return self.get_portfolio_group_commands_with_http_info(scope, code, from_as_at, to_as_at, filter, **kwargs)  # noqa: E501

    @validate_arguments
    def get_portfolio_group_commands_with_http_info(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group to retrieve the commands for.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group to retrieve the commands for. Together with the scope this uniquely identifies the portfolio group.")], from_as_at : Annotated[Optional[datetime], Field(description="The lower bound asAt datetime (inclusive) from which to retrieve commands. There is no lower bound if this is not specified.")] = None, to_as_at : Annotated[Optional[datetime], Field(description="The upper bound asAt datetime (inclusive) from which to retrieve commands. There is no upper bound if this is not specified.")] = None, filter : Annotated[Optional[StrictStr], Field( description="Expression to filter the result set.               For example, to filter on the User ID, use \"userId.id eq 'string'\"              Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.")] = None, **kwargs) -> ApiResponse:  # noqa: E501
        """GetPortfolioGroupCommands: Get portfolio group commands  # noqa: E501

        Gets all the commands that modified a single portfolio group.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.get_portfolio_group_commands_with_http_info(scope, code, from_as_at, to_as_at, filter, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the portfolio group to retrieve the commands for. (required)
        :type scope: str
        :param code: The code of the portfolio group to retrieve the commands for. Together with the scope this uniquely identifies the portfolio group. (required)
        :type code: str
        :param from_as_at: The lower bound asAt datetime (inclusive) from which to retrieve commands. There is no lower bound if this is not specified.
        :type from_as_at: datetime
        :param to_as_at: The upper bound asAt datetime (inclusive) from which to retrieve commands. There is no upper bound if this is not specified.
        :type to_as_at: datetime
        :param filter: Expression to filter the result set.               For example, to filter on the User ID, use \"userId.id eq 'string'\"              Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.
        :type filter: str
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _preload_content: if False, the ApiResponse.data will
                                 be set to none and raw_data will store the
                                 HTTP response body without reading/decoding.
                                 Default is True.
        :type _preload_content: bool, optional
        :param _return_http_data_only: response data instead of ApiResponse
                                       object with status code, headers, etc
        :type _return_http_data_only: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the authentication
                              in the spec for a single request.
        :type _request_auth: dict, optional
        :type _content_type: string, optional: force content-type for the request
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: tuple(ResourceListOfProcessedCommand, status_code(int), headers(HTTPHeaderDict))
        """

        _params = locals()

        _all_params = [
            'scope',
            'code',
            'from_as_at',
            'to_as_at',
            'filter'
        ]
        _all_params.extend(
            [
                'async_req',
                '_return_http_data_only',
                '_preload_content',
                '_request_timeout',
                '_request_auth',
                '_content_type',
                '_headers',
                'opts'
            ]
        )

        # validate the arguments
        for _key, _val in _params['kwargs'].items():
            if _key not in _all_params:
                raise ApiTypeError(
                    "Got an unexpected keyword argument '%s'"
                    " to method get_portfolio_group_commands" % _key
                )
            _params[_key] = _val
        del _params['kwargs']

        _collection_formats = {}

        # process the path parameters
        _path_params = {}
        if _params['scope']:
            _path_params['scope'] = _params['scope']

        if _params['code']:
            _path_params['code'] = _params['code']


        # process the query parameters
        _query_params = []
        if _params.get('from_as_at') is not None:  # noqa: E501
            if isinstance(_params['from_as_at'], datetime):
                _query_params.append(('fromAsAt', _params['from_as_at'].strftime(self.api_client.configuration.datetime_format)))
            else:
                _query_params.append(('fromAsAt', _params['from_as_at']))

        if _params.get('to_as_at') is not None:  # noqa: E501
            if isinstance(_params['to_as_at'], datetime):
                _query_params.append(('toAsAt', _params['to_as_at'].strftime(self.api_client.configuration.datetime_format)))
            else:
                _query_params.append(('toAsAt', _params['to_as_at']))

        if _params.get('filter') is not None:  # noqa: E501
            _query_params.append(('filter', _params['filter']))

        # process the header parameters
        _header_params = dict(_params.get('_headers', {}))
        # process the form parameters
        _form_params = []
        _files = {}
        # process the body parameter
        _body_params = None
        # set the HTTP header `Accept`
        _header_params['Accept'] = self.api_client.select_header_accept(
            ['text/plain', 'application/json', 'text/json'])  # noqa: E501

        # authentication setting
        _auth_settings = ['oauth2']  # noqa: E501

        _response_types_map = {
            '200': "ResourceListOfProcessedCommand",
            '400': "LusidValidationProblemDetails",
        }

        return self.api_client.call_api(
            '/api/portfoliogroups/{scope}/{code}/commands', 'GET',
            _path_params,
            _query_params,
            _header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            response_types_map=_response_types_map,
            auth_settings=_auth_settings,
            async_req=_params.get('async_req'),
            _return_http_data_only=_params.get('_return_http_data_only'),  # noqa: E501
            _preload_content=_params.get('_preload_content', True),
            _request_timeout=_params.get('_request_timeout'),
            opts=_params.get('opts'),
            collection_formats=_collection_formats,
            _request_auth=_params.get('_request_auth'))


    @overload
    async def get_portfolio_group_expansion(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group to expand.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group to expand. Together with the scope this uniquely identifies the portfolio              group to expand.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label at which to expand the portfolio group. Defaults to the current LUSID system datetime if not specified.")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to expand the portfolio group. Defaults to return the latest version of each portfolio in the group if not specified.")] = None, property_filter : Annotated[Optional[List[StrictStr]], Field(description="The restricted list of property keys from the \"Portfolio\" domain which will be decorated onto each portfolio. These take the format {domain}/{scope}/{code} e.g. \"Portfolio/Manager/Id\".")] = None, **kwargs) -> ExpandedGroup:  # noqa: E501
        ...

    @overload
    def get_portfolio_group_expansion(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group to expand.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group to expand. Together with the scope this uniquely identifies the portfolio              group to expand.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label at which to expand the portfolio group. Defaults to the current LUSID system datetime if not specified.")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to expand the portfolio group. Defaults to return the latest version of each portfolio in the group if not specified.")] = None, property_filter : Annotated[Optional[List[StrictStr]], Field(description="The restricted list of property keys from the \"Portfolio\" domain which will be decorated onto each portfolio. These take the format {domain}/{scope}/{code} e.g. \"Portfolio/Manager/Id\".")] = None, async_req: Optional[bool]=True, **kwargs) -> ExpandedGroup:  # noqa: E501
        ...

    @validate_arguments
    def get_portfolio_group_expansion(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group to expand.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group to expand. Together with the scope this uniquely identifies the portfolio              group to expand.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label at which to expand the portfolio group. Defaults to the current LUSID system datetime if not specified.")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to expand the portfolio group. Defaults to return the latest version of each portfolio in the group if not specified.")] = None, property_filter : Annotated[Optional[List[StrictStr]], Field(description="The restricted list of property keys from the \"Portfolio\" domain which will be decorated onto each portfolio. These take the format {domain}/{scope}/{code} e.g. \"Portfolio/Manager/Id\".")] = None, async_req: Optional[bool]=None, **kwargs) -> Union[ExpandedGroup, Awaitable[ExpandedGroup]]:  # noqa: E501
        """[EARLY ACCESS] GetPortfolioGroupExpansion: Get portfolio group expansion  # noqa: E501

        List all the portfolios in a group, including all portfolios within sub groups in the group. Each portfolio will be decorated with all of its properties unless a property filter is specified.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.get_portfolio_group_expansion(scope, code, effective_at, as_at, property_filter, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the portfolio group to expand. (required)
        :type scope: str
        :param code: The code of the portfolio group to expand. Together with the scope this uniquely identifies the portfolio              group to expand. (required)
        :type code: str
        :param effective_at: The effective datetime or cut label at which to expand the portfolio group. Defaults to the current LUSID system datetime if not specified.
        :type effective_at: str
        :param as_at: The asAt datetime at which to expand the portfolio group. Defaults to return the latest version of each portfolio in the group if not specified.
        :type as_at: datetime
        :param property_filter: The restricted list of property keys from the \"Portfolio\" domain which will be decorated onto each portfolio. These take the format {domain}/{scope}/{code} e.g. \"Portfolio/Manager/Id\".
        :type property_filter: List[str]
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: ExpandedGroup
        """
        kwargs['_return_http_data_only'] = True
        if '_preload_content' in kwargs:
            message = "Error! Please call the get_portfolio_group_expansion_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data"  # noqa: E501
            raise ValueError(message)
        if async_req is not None:
            kwargs['async_req'] = async_req
        return self.get_portfolio_group_expansion_with_http_info(scope, code, effective_at, as_at, property_filter, **kwargs)  # noqa: E501

    @validate_arguments
    def get_portfolio_group_expansion_with_http_info(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group to expand.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group to expand. Together with the scope this uniquely identifies the portfolio              group to expand.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label at which to expand the portfolio group. Defaults to the current LUSID system datetime if not specified.")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to expand the portfolio group. Defaults to return the latest version of each portfolio in the group if not specified.")] = None, property_filter : Annotated[Optional[List[StrictStr]], Field(description="The restricted list of property keys from the \"Portfolio\" domain which will be decorated onto each portfolio. These take the format {domain}/{scope}/{code} e.g. \"Portfolio/Manager/Id\".")] = None, **kwargs) -> ApiResponse:  # noqa: E501
        """[EARLY ACCESS] GetPortfolioGroupExpansion: Get portfolio group expansion  # noqa: E501

        List all the portfolios in a group, including all portfolios within sub groups in the group. Each portfolio will be decorated with all of its properties unless a property filter is specified.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.get_portfolio_group_expansion_with_http_info(scope, code, effective_at, as_at, property_filter, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the portfolio group to expand. (required)
        :type scope: str
        :param code: The code of the portfolio group to expand. Together with the scope this uniquely identifies the portfolio              group to expand. (required)
        :type code: str
        :param effective_at: The effective datetime or cut label at which to expand the portfolio group. Defaults to the current LUSID system datetime if not specified.
        :type effective_at: str
        :param as_at: The asAt datetime at which to expand the portfolio group. Defaults to return the latest version of each portfolio in the group if not specified.
        :type as_at: datetime
        :param property_filter: The restricted list of property keys from the \"Portfolio\" domain which will be decorated onto each portfolio. These take the format {domain}/{scope}/{code} e.g. \"Portfolio/Manager/Id\".
        :type property_filter: List[str]
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _preload_content: if False, the ApiResponse.data will
                                 be set to none and raw_data will store the
                                 HTTP response body without reading/decoding.
                                 Default is True.
        :type _preload_content: bool, optional
        :param _return_http_data_only: response data instead of ApiResponse
                                       object with status code, headers, etc
        :type _return_http_data_only: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the authentication
                              in the spec for a single request.
        :type _request_auth: dict, optional
        :type _content_type: string, optional: force content-type for the request
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: tuple(ExpandedGroup, status_code(int), headers(HTTPHeaderDict))
        """

        _params = locals()

        _all_params = [
            'scope',
            'code',
            'effective_at',
            'as_at',
            'property_filter'
        ]
        _all_params.extend(
            [
                'async_req',
                '_return_http_data_only',
                '_preload_content',
                '_request_timeout',
                '_request_auth',
                '_content_type',
                '_headers',
                'opts'
            ]
        )

        # validate the arguments
        for _key, _val in _params['kwargs'].items():
            if _key not in _all_params:
                raise ApiTypeError(
                    "Got an unexpected keyword argument '%s'"
                    " to method get_portfolio_group_expansion" % _key
                )
            _params[_key] = _val
        del _params['kwargs']

        _collection_formats = {}

        # process the path parameters
        _path_params = {}
        if _params['scope']:
            _path_params['scope'] = _params['scope']

        if _params['code']:
            _path_params['code'] = _params['code']


        # process the query parameters
        _query_params = []
        if _params.get('effective_at') is not None:  # noqa: E501
            _query_params.append(('effectiveAt', _params['effective_at']))

        if _params.get('as_at') is not None:  # noqa: E501
            if isinstance(_params['as_at'], datetime):
                _query_params.append(('asAt', _params['as_at'].strftime(self.api_client.configuration.datetime_format)))
            else:
                _query_params.append(('asAt', _params['as_at']))

        if _params.get('property_filter') is not None:  # noqa: E501
            _query_params.append(('propertyFilter', _params['property_filter']))
            _collection_formats['propertyFilter'] = 'multi'

        # process the header parameters
        _header_params = dict(_params.get('_headers', {}))
        # process the form parameters
        _form_params = []
        _files = {}
        # process the body parameter
        _body_params = None
        # set the HTTP header `Accept`
        _header_params['Accept'] = self.api_client.select_header_accept(
            ['text/plain', 'application/json', 'text/json'])  # noqa: E501

        # authentication setting
        _auth_settings = ['oauth2']  # noqa: E501

        _response_types_map = {
            '200': "ExpandedGroup",
            '400': "LusidValidationProblemDetails",
        }

        return self.api_client.call_api(
            '/api/portfoliogroups/{scope}/{code}/expansion', 'GET',
            _path_params,
            _query_params,
            _header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            response_types_map=_response_types_map,
            auth_settings=_auth_settings,
            async_req=_params.get('async_req'),
            _return_http_data_only=_params.get('_return_http_data_only'),  # noqa: E501
            _preload_content=_params.get('_preload_content', True),
            _request_timeout=_params.get('_request_timeout'),
            opts=_params.get('opts'),
            collection_formats=_collection_formats,
            _request_auth=_params.get('_request_auth'))


    @overload
    async def get_portfolio_group_metadata(self, scope : Annotated[StrictStr, Field(..., description="The scope of the Portfolio Group")], code : Annotated[StrictStr, Field(..., description="The Portfolio Group code")], effective_at : Annotated[Optional[StrictStr], Field( description="The effectiveAt datetime at which to retrieve the Access Metadata")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to retrieve the Access Metadata")] = None, **kwargs) -> Dict[str, List[AccessMetadataValue]]:  # noqa: E501
        ...

    @overload
    def get_portfolio_group_metadata(self, scope : Annotated[StrictStr, Field(..., description="The scope of the Portfolio Group")], code : Annotated[StrictStr, Field(..., description="The Portfolio Group code")], effective_at : Annotated[Optional[StrictStr], Field( description="The effectiveAt datetime at which to retrieve the Access Metadata")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to retrieve the Access Metadata")] = None, async_req: Optional[bool]=True, **kwargs) -> Dict[str, List[AccessMetadataValue]]:  # noqa: E501
        ...

    @validate_arguments
    def get_portfolio_group_metadata(self, scope : Annotated[StrictStr, Field(..., description="The scope of the Portfolio Group")], code : Annotated[StrictStr, Field(..., description="The Portfolio Group code")], effective_at : Annotated[Optional[StrictStr], Field( description="The effectiveAt datetime at which to retrieve the Access Metadata")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to retrieve the Access Metadata")] = None, async_req: Optional[bool]=None, **kwargs) -> Union[Dict[str, List[AccessMetadataValue]], Awaitable[Dict[str, List[AccessMetadataValue]]]]:  # noqa: E501
        """[EARLY ACCESS] GetPortfolioGroupMetadata: Get Access Metadata rules for Portfolio Group  # noqa: E501

        Pass the scope and Portfolio Group code parameters to retrieve the associated Access Metadata  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.get_portfolio_group_metadata(scope, code, effective_at, as_at, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the Portfolio Group (required)
        :type scope: str
        :param code: The Portfolio Group code (required)
        :type code: str
        :param effective_at: The effectiveAt datetime at which to retrieve the Access Metadata
        :type effective_at: str
        :param as_at: The asAt datetime at which to retrieve the Access Metadata
        :type as_at: datetime
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: Dict[str, List[AccessMetadataValue]]
        """
        kwargs['_return_http_data_only'] = True
        if '_preload_content' in kwargs:
            message = "Error! Please call the get_portfolio_group_metadata_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data"  # noqa: E501
            raise ValueError(message)
        if async_req is not None:
            kwargs['async_req'] = async_req
        return self.get_portfolio_group_metadata_with_http_info(scope, code, effective_at, as_at, **kwargs)  # noqa: E501

    @validate_arguments
    def get_portfolio_group_metadata_with_http_info(self, scope : Annotated[StrictStr, Field(..., description="The scope of the Portfolio Group")], code : Annotated[StrictStr, Field(..., description="The Portfolio Group code")], effective_at : Annotated[Optional[StrictStr], Field( description="The effectiveAt datetime at which to retrieve the Access Metadata")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to retrieve the Access Metadata")] = None, **kwargs) -> ApiResponse:  # noqa: E501
        """[EARLY ACCESS] GetPortfolioGroupMetadata: Get Access Metadata rules for Portfolio Group  # noqa: E501

        Pass the scope and Portfolio Group code parameters to retrieve the associated Access Metadata  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.get_portfolio_group_metadata_with_http_info(scope, code, effective_at, as_at, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the Portfolio Group (required)
        :type scope: str
        :param code: The Portfolio Group code (required)
        :type code: str
        :param effective_at: The effectiveAt datetime at which to retrieve the Access Metadata
        :type effective_at: str
        :param as_at: The asAt datetime at which to retrieve the Access Metadata
        :type as_at: datetime
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _preload_content: if False, the ApiResponse.data will
                                 be set to none and raw_data will store the
                                 HTTP response body without reading/decoding.
                                 Default is True.
        :type _preload_content: bool, optional
        :param _return_http_data_only: response data instead of ApiResponse
                                       object with status code, headers, etc
        :type _return_http_data_only: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the authentication
                              in the spec for a single request.
        :type _request_auth: dict, optional
        :type _content_type: string, optional: force content-type for the request
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: tuple(Dict[str, List[AccessMetadataValue]], status_code(int), headers(HTTPHeaderDict))
        """

        _params = locals()

        _all_params = [
            'scope',
            'code',
            'effective_at',
            'as_at'
        ]
        _all_params.extend(
            [
                'async_req',
                '_return_http_data_only',
                '_preload_content',
                '_request_timeout',
                '_request_auth',
                '_content_type',
                '_headers',
                'opts'
            ]
        )

        # validate the arguments
        for _key, _val in _params['kwargs'].items():
            if _key not in _all_params:
                raise ApiTypeError(
                    "Got an unexpected keyword argument '%s'"
                    " to method get_portfolio_group_metadata" % _key
                )
            _params[_key] = _val
        del _params['kwargs']

        _collection_formats = {}

        # process the path parameters
        _path_params = {}
        if _params['scope']:
            _path_params['scope'] = _params['scope']

        if _params['code']:
            _path_params['code'] = _params['code']


        # process the query parameters
        _query_params = []
        if _params.get('effective_at') is not None:  # noqa: E501
            _query_params.append(('effectiveAt', _params['effective_at']))

        if _params.get('as_at') is not None:  # noqa: E501
            if isinstance(_params['as_at'], datetime):
                _query_params.append(('asAt', _params['as_at'].strftime(self.api_client.configuration.datetime_format)))
            else:
                _query_params.append(('asAt', _params['as_at']))

        # process the header parameters
        _header_params = dict(_params.get('_headers', {}))
        # process the form parameters
        _form_params = []
        _files = {}
        # process the body parameter
        _body_params = None
        # set the HTTP header `Accept`
        _header_params['Accept'] = self.api_client.select_header_accept(
            ['text/plain', 'application/json', 'text/json'])  # noqa: E501

        # authentication setting
        _auth_settings = ['oauth2']  # noqa: E501

        _response_types_map = {
            '200': "Dict[str, List[AccessMetadataValue]]",
            '400': "LusidValidationProblemDetails",
        }

        return self.api_client.call_api(
            '/api/portfoliogroups/{scope}/{code}/metadata', 'GET',
            _path_params,
            _query_params,
            _header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            response_types_map=_response_types_map,
            auth_settings=_auth_settings,
            async_req=_params.get('async_req'),
            _return_http_data_only=_params.get('_return_http_data_only'),  # noqa: E501
            _preload_content=_params.get('_preload_content', True),
            _request_timeout=_params.get('_request_timeout'),
            opts=_params.get('opts'),
            collection_formats=_collection_formats,
            _request_auth=_params.get('_request_auth'))


    @overload
    async def get_portfolio_group_property_time_series(self, scope : Annotated[StrictStr, Field(..., description="The scope of the group.")], code : Annotated[StrictStr, Field(..., description="The code of the group. Together with the scope this uniquely identifies              the portfolio group.")], property_key : Annotated[StrictStr, Field(..., description="The property key of the property that will have its history shown. These must be in the format {domain}/{scope}/{code} e.g. \"PortfolioGroup/Manager/Id\".              Each property must be from the \"PortfolioGroup\" domain.")], portfolio_group_effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime used to resolve the portfolio group. Defaults to the current LUSID system datetime if not specified.")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to list the portfolio group's property history. Defaults to return the current datetime if not supplied.")] = None, filter : Annotated[Optional[StrictStr], Field( description="Expression to filter the result set. Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.")] = None, page : Annotated[Optional[StrictStr], Field( description="The pagination token to use to continue listing properties from a previous call to get property time series.              This value is returned from the previous call. If a pagination token is provided the filter, effectiveAt, and asAt fields              must not have changed since the original request.")] = None, limit : Annotated[Optional[StrictInt], Field(description="When paginating, limit the number of returned results to this many.")] = None, **kwargs) -> ResourceListOfPropertyInterval:  # noqa: E501
        ...

    @overload
    def get_portfolio_group_property_time_series(self, scope : Annotated[StrictStr, Field(..., description="The scope of the group.")], code : Annotated[StrictStr, Field(..., description="The code of the group. Together with the scope this uniquely identifies              the portfolio group.")], property_key : Annotated[StrictStr, Field(..., description="The property key of the property that will have its history shown. These must be in the format {domain}/{scope}/{code} e.g. \"PortfolioGroup/Manager/Id\".              Each property must be from the \"PortfolioGroup\" domain.")], portfolio_group_effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime used to resolve the portfolio group. Defaults to the current LUSID system datetime if not specified.")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to list the portfolio group's property history. Defaults to return the current datetime if not supplied.")] = None, filter : Annotated[Optional[StrictStr], Field( description="Expression to filter the result set. Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.")] = None, page : Annotated[Optional[StrictStr], Field( description="The pagination token to use to continue listing properties from a previous call to get property time series.              This value is returned from the previous call. If a pagination token is provided the filter, effectiveAt, and asAt fields              must not have changed since the original request.")] = None, limit : Annotated[Optional[StrictInt], Field(description="When paginating, limit the number of returned results to this many.")] = None, async_req: Optional[bool]=True, **kwargs) -> ResourceListOfPropertyInterval:  # noqa: E501
        ...

    @validate_arguments
    def get_portfolio_group_property_time_series(self, scope : Annotated[StrictStr, Field(..., description="The scope of the group.")], code : Annotated[StrictStr, Field(..., description="The code of the group. Together with the scope this uniquely identifies              the portfolio group.")], property_key : Annotated[StrictStr, Field(..., description="The property key of the property that will have its history shown. These must be in the format {domain}/{scope}/{code} e.g. \"PortfolioGroup/Manager/Id\".              Each property must be from the \"PortfolioGroup\" domain.")], portfolio_group_effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime used to resolve the portfolio group. Defaults to the current LUSID system datetime if not specified.")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to list the portfolio group's property history. Defaults to return the current datetime if not supplied.")] = None, filter : Annotated[Optional[StrictStr], Field( description="Expression to filter the result set. Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.")] = None, page : Annotated[Optional[StrictStr], Field( description="The pagination token to use to continue listing properties from a previous call to get property time series.              This value is returned from the previous call. If a pagination token is provided the filter, effectiveAt, and asAt fields              must not have changed since the original request.")] = None, limit : Annotated[Optional[StrictInt], Field(description="When paginating, limit the number of returned results to this many.")] = None, async_req: Optional[bool]=None, **kwargs) -> Union[ResourceListOfPropertyInterval, Awaitable[ResourceListOfPropertyInterval]]:  # noqa: E501
        """[EARLY ACCESS] GetPortfolioGroupPropertyTimeSeries: Get the time series of a portfolio group property  # noqa: E501

        List the complete time series of a portfolio group property.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.get_portfolio_group_property_time_series(scope, code, property_key, portfolio_group_effective_at, as_at, filter, page, limit, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the group. (required)
        :type scope: str
        :param code: The code of the group. Together with the scope this uniquely identifies              the portfolio group. (required)
        :type code: str
        :param property_key: The property key of the property that will have its history shown. These must be in the format {domain}/{scope}/{code} e.g. \"PortfolioGroup/Manager/Id\".              Each property must be from the \"PortfolioGroup\" domain. (required)
        :type property_key: str
        :param portfolio_group_effective_at: The effective datetime used to resolve the portfolio group. Defaults to the current LUSID system datetime if not specified.
        :type portfolio_group_effective_at: str
        :param as_at: The asAt datetime at which to list the portfolio group's property history. Defaults to return the current datetime if not supplied.
        :type as_at: datetime
        :param filter: Expression to filter the result set. Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.
        :type filter: str
        :param page: The pagination token to use to continue listing properties from a previous call to get property time series.              This value is returned from the previous call. If a pagination token is provided the filter, effectiveAt, and asAt fields              must not have changed since the original request.
        :type page: str
        :param limit: When paginating, limit the number of returned results to this many.
        :type limit: int
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: ResourceListOfPropertyInterval
        """
        kwargs['_return_http_data_only'] = True
        if '_preload_content' in kwargs:
            message = "Error! Please call the get_portfolio_group_property_time_series_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data"  # noqa: E501
            raise ValueError(message)
        if async_req is not None:
            kwargs['async_req'] = async_req
        return self.get_portfolio_group_property_time_series_with_http_info(scope, code, property_key, portfolio_group_effective_at, as_at, filter, page, limit, **kwargs)  # noqa: E501

    @validate_arguments
    def get_portfolio_group_property_time_series_with_http_info(self, scope : Annotated[StrictStr, Field(..., description="The scope of the group.")], code : Annotated[StrictStr, Field(..., description="The code of the group. Together with the scope this uniquely identifies              the portfolio group.")], property_key : Annotated[StrictStr, Field(..., description="The property key of the property that will have its history shown. These must be in the format {domain}/{scope}/{code} e.g. \"PortfolioGroup/Manager/Id\".              Each property must be from the \"PortfolioGroup\" domain.")], portfolio_group_effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime used to resolve the portfolio group. Defaults to the current LUSID system datetime if not specified.")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to list the portfolio group's property history. Defaults to return the current datetime if not supplied.")] = None, filter : Annotated[Optional[StrictStr], Field( description="Expression to filter the result set. Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.")] = None, page : Annotated[Optional[StrictStr], Field( description="The pagination token to use to continue listing properties from a previous call to get property time series.              This value is returned from the previous call. If a pagination token is provided the filter, effectiveAt, and asAt fields              must not have changed since the original request.")] = None, limit : Annotated[Optional[StrictInt], Field(description="When paginating, limit the number of returned results to this many.")] = None, **kwargs) -> ApiResponse:  # noqa: E501
        """[EARLY ACCESS] GetPortfolioGroupPropertyTimeSeries: Get the time series of a portfolio group property  # noqa: E501

        List the complete time series of a portfolio group property.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.get_portfolio_group_property_time_series_with_http_info(scope, code, property_key, portfolio_group_effective_at, as_at, filter, page, limit, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the group. (required)
        :type scope: str
        :param code: The code of the group. Together with the scope this uniquely identifies              the portfolio group. (required)
        :type code: str
        :param property_key: The property key of the property that will have its history shown. These must be in the format {domain}/{scope}/{code} e.g. \"PortfolioGroup/Manager/Id\".              Each property must be from the \"PortfolioGroup\" domain. (required)
        :type property_key: str
        :param portfolio_group_effective_at: The effective datetime used to resolve the portfolio group. Defaults to the current LUSID system datetime if not specified.
        :type portfolio_group_effective_at: str
        :param as_at: The asAt datetime at which to list the portfolio group's property history. Defaults to return the current datetime if not supplied.
        :type as_at: datetime
        :param filter: Expression to filter the result set. Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.
        :type filter: str
        :param page: The pagination token to use to continue listing properties from a previous call to get property time series.              This value is returned from the previous call. If a pagination token is provided the filter, effectiveAt, and asAt fields              must not have changed since the original request.
        :type page: str
        :param limit: When paginating, limit the number of returned results to this many.
        :type limit: int
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _preload_content: if False, the ApiResponse.data will
                                 be set to none and raw_data will store the
                                 HTTP response body without reading/decoding.
                                 Default is True.
        :type _preload_content: bool, optional
        :param _return_http_data_only: response data instead of ApiResponse
                                       object with status code, headers, etc
        :type _return_http_data_only: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the authentication
                              in the spec for a single request.
        :type _request_auth: dict, optional
        :type _content_type: string, optional: force content-type for the request
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: tuple(ResourceListOfPropertyInterval, status_code(int), headers(HTTPHeaderDict))
        """

        _params = locals()

        _all_params = [
            'scope',
            'code',
            'property_key',
            'portfolio_group_effective_at',
            'as_at',
            'filter',
            'page',
            'limit'
        ]
        _all_params.extend(
            [
                'async_req',
                '_return_http_data_only',
                '_preload_content',
                '_request_timeout',
                '_request_auth',
                '_content_type',
                '_headers',
                'opts'
            ]
        )

        # validate the arguments
        for _key, _val in _params['kwargs'].items():
            if _key not in _all_params:
                raise ApiTypeError(
                    "Got an unexpected keyword argument '%s'"
                    " to method get_portfolio_group_property_time_series" % _key
                )
            _params[_key] = _val
        del _params['kwargs']

        _collection_formats = {}

        # process the path parameters
        _path_params = {}
        if _params['scope']:
            _path_params['scope'] = _params['scope']

        if _params['code']:
            _path_params['code'] = _params['code']


        # process the query parameters
        _query_params = []
        if _params.get('property_key') is not None:  # noqa: E501
            _query_params.append(('propertyKey', _params['property_key']))

        if _params.get('portfolio_group_effective_at') is not None:  # noqa: E501
            _query_params.append(('portfolioGroupEffectiveAt', _params['portfolio_group_effective_at']))

        if _params.get('as_at') is not None:  # noqa: E501
            if isinstance(_params['as_at'], datetime):
                _query_params.append(('asAt', _params['as_at'].strftime(self.api_client.configuration.datetime_format)))
            else:
                _query_params.append(('asAt', _params['as_at']))

        if _params.get('filter') is not None:  # noqa: E501
            _query_params.append(('filter', _params['filter']))

        if _params.get('page') is not None:  # noqa: E501
            _query_params.append(('page', _params['page']))

        if _params.get('limit') is not None:  # noqa: E501
            _query_params.append(('limit', _params['limit']))

        # process the header parameters
        _header_params = dict(_params.get('_headers', {}))
        # process the form parameters
        _form_params = []
        _files = {}
        # process the body parameter
        _body_params = None
        # set the HTTP header `Accept`
        _header_params['Accept'] = self.api_client.select_header_accept(
            ['text/plain', 'application/json', 'text/json'])  # noqa: E501

        # authentication setting
        _auth_settings = ['oauth2']  # noqa: E501

        _response_types_map = {
            '200': "ResourceListOfPropertyInterval",
            '400': "LusidValidationProblemDetails",
        }

        return self.api_client.call_api(
            '/api/portfoliogroups/{scope}/{code}/properties/time-series', 'GET',
            _path_params,
            _query_params,
            _header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            response_types_map=_response_types_map,
            auth_settings=_auth_settings,
            async_req=_params.get('async_req'),
            _return_http_data_only=_params.get('_return_http_data_only'),  # noqa: E501
            _preload_content=_params.get('_preload_content', True),
            _request_timeout=_params.get('_request_timeout'),
            opts=_params.get('opts'),
            collection_formats=_collection_formats,
            _request_auth=_params.get('_request_auth'))


    @overload
    async def get_portfolio_group_relations(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group. Together with the scope this uniquely identifies              the portfolio group.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label at which to retrieve relations. Defaults to the current LUSID system datetime if not specified.")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to retrieve relations. Defaults to return the latest LUSID AsAt time if not specified.")] = None, filter : Annotated[Optional[StrictStr], Field( description="Expression to filter the relations. Users should provide null or empty string for this field until further notice.")] = None, identifier_types : Annotated[Optional[List[StrictStr]], Field(description="Identifiers types (as property keys) used for referencing Persons or Legal Entities. These take the format              {domain}/{scope}/{code} e.g. \"Person/CompanyDetails/Role\". They must be from the \"Person\" or \"LegalEntity\" domain.              Only identifier types stated will be used to look up relevant entities in relations. If not applicable, provide an empty array.")] = None, **kwargs) -> ResourceListOfRelation:  # noqa: E501
        ...

    @overload
    def get_portfolio_group_relations(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group. Together with the scope this uniquely identifies              the portfolio group.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label at which to retrieve relations. Defaults to the current LUSID system datetime if not specified.")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to retrieve relations. Defaults to return the latest LUSID AsAt time if not specified.")] = None, filter : Annotated[Optional[StrictStr], Field( description="Expression to filter the relations. Users should provide null or empty string for this field until further notice.")] = None, identifier_types : Annotated[Optional[List[StrictStr]], Field(description="Identifiers types (as property keys) used for referencing Persons or Legal Entities. These take the format              {domain}/{scope}/{code} e.g. \"Person/CompanyDetails/Role\". They must be from the \"Person\" or \"LegalEntity\" domain.              Only identifier types stated will be used to look up relevant entities in relations. If not applicable, provide an empty array.")] = None, async_req: Optional[bool]=True, **kwargs) -> ResourceListOfRelation:  # noqa: E501
        ...

    @validate_arguments
    def get_portfolio_group_relations(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group. Together with the scope this uniquely identifies              the portfolio group.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label at which to retrieve relations. Defaults to the current LUSID system datetime if not specified.")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to retrieve relations. Defaults to return the latest LUSID AsAt time if not specified.")] = None, filter : Annotated[Optional[StrictStr], Field( description="Expression to filter the relations. Users should provide null or empty string for this field until further notice.")] = None, identifier_types : Annotated[Optional[List[StrictStr]], Field(description="Identifiers types (as property keys) used for referencing Persons or Legal Entities. These take the format              {domain}/{scope}/{code} e.g. \"Person/CompanyDetails/Role\". They must be from the \"Person\" or \"LegalEntity\" domain.              Only identifier types stated will be used to look up relevant entities in relations. If not applicable, provide an empty array.")] = None, async_req: Optional[bool]=None, **kwargs) -> Union[ResourceListOfRelation, Awaitable[ResourceListOfRelation]]:  # noqa: E501
        """[EXPERIMENTAL] GetPortfolioGroupRelations: Get Relations for Portfolio Group  # noqa: E501

        Get relations for the specified Portfolio Group  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.get_portfolio_group_relations(scope, code, effective_at, as_at, filter, identifier_types, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the portfolio group. (required)
        :type scope: str
        :param code: The code of the portfolio group. Together with the scope this uniquely identifies              the portfolio group. (required)
        :type code: str
        :param effective_at: The effective datetime or cut label at which to retrieve relations. Defaults to the current LUSID system datetime if not specified.
        :type effective_at: str
        :param as_at: The asAt datetime at which to retrieve relations. Defaults to return the latest LUSID AsAt time if not specified.
        :type as_at: datetime
        :param filter: Expression to filter the relations. Users should provide null or empty string for this field until further notice.
        :type filter: str
        :param identifier_types: Identifiers types (as property keys) used for referencing Persons or Legal Entities. These take the format              {domain}/{scope}/{code} e.g. \"Person/CompanyDetails/Role\". They must be from the \"Person\" or \"LegalEntity\" domain.              Only identifier types stated will be used to look up relevant entities in relations. If not applicable, provide an empty array.
        :type identifier_types: List[str]
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: ResourceListOfRelation
        """
        kwargs['_return_http_data_only'] = True
        if '_preload_content' in kwargs:
            message = "Error! Please call the get_portfolio_group_relations_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data"  # noqa: E501
            raise ValueError(message)
        if async_req is not None:
            kwargs['async_req'] = async_req
        return self.get_portfolio_group_relations_with_http_info(scope, code, effective_at, as_at, filter, identifier_types, **kwargs)  # noqa: E501

    @validate_arguments
    def get_portfolio_group_relations_with_http_info(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group. Together with the scope this uniquely identifies              the portfolio group.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label at which to retrieve relations. Defaults to the current LUSID system datetime if not specified.")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to retrieve relations. Defaults to return the latest LUSID AsAt time if not specified.")] = None, filter : Annotated[Optional[StrictStr], Field( description="Expression to filter the relations. Users should provide null or empty string for this field until further notice.")] = None, identifier_types : Annotated[Optional[List[StrictStr]], Field(description="Identifiers types (as property keys) used for referencing Persons or Legal Entities. These take the format              {domain}/{scope}/{code} e.g. \"Person/CompanyDetails/Role\". They must be from the \"Person\" or \"LegalEntity\" domain.              Only identifier types stated will be used to look up relevant entities in relations. If not applicable, provide an empty array.")] = None, **kwargs) -> ApiResponse:  # noqa: E501
        """[EXPERIMENTAL] GetPortfolioGroupRelations: Get Relations for Portfolio Group  # noqa: E501

        Get relations for the specified Portfolio Group  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.get_portfolio_group_relations_with_http_info(scope, code, effective_at, as_at, filter, identifier_types, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the portfolio group. (required)
        :type scope: str
        :param code: The code of the portfolio group. Together with the scope this uniquely identifies              the portfolio group. (required)
        :type code: str
        :param effective_at: The effective datetime or cut label at which to retrieve relations. Defaults to the current LUSID system datetime if not specified.
        :type effective_at: str
        :param as_at: The asAt datetime at which to retrieve relations. Defaults to return the latest LUSID AsAt time if not specified.
        :type as_at: datetime
        :param filter: Expression to filter the relations. Users should provide null or empty string for this field until further notice.
        :type filter: str
        :param identifier_types: Identifiers types (as property keys) used for referencing Persons or Legal Entities. These take the format              {domain}/{scope}/{code} e.g. \"Person/CompanyDetails/Role\". They must be from the \"Person\" or \"LegalEntity\" domain.              Only identifier types stated will be used to look up relevant entities in relations. If not applicable, provide an empty array.
        :type identifier_types: List[str]
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _preload_content: if False, the ApiResponse.data will
                                 be set to none and raw_data will store the
                                 HTTP response body without reading/decoding.
                                 Default is True.
        :type _preload_content: bool, optional
        :param _return_http_data_only: response data instead of ApiResponse
                                       object with status code, headers, etc
        :type _return_http_data_only: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the authentication
                              in the spec for a single request.
        :type _request_auth: dict, optional
        :type _content_type: string, optional: force content-type for the request
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: tuple(ResourceListOfRelation, status_code(int), headers(HTTPHeaderDict))
        """

        _params = locals()

        _all_params = [
            'scope',
            'code',
            'effective_at',
            'as_at',
            'filter',
            'identifier_types'
        ]
        _all_params.extend(
            [
                'async_req',
                '_return_http_data_only',
                '_preload_content',
                '_request_timeout',
                '_request_auth',
                '_content_type',
                '_headers',
                'opts'
            ]
        )

        # validate the arguments
        for _key, _val in _params['kwargs'].items():
            if _key not in _all_params:
                raise ApiTypeError(
                    "Got an unexpected keyword argument '%s'"
                    " to method get_portfolio_group_relations" % _key
                )
            _params[_key] = _val
        del _params['kwargs']

        _collection_formats = {}

        # process the path parameters
        _path_params = {}
        if _params['scope']:
            _path_params['scope'] = _params['scope']

        if _params['code']:
            _path_params['code'] = _params['code']


        # process the query parameters
        _query_params = []
        if _params.get('effective_at') is not None:  # noqa: E501
            _query_params.append(('effectiveAt', _params['effective_at']))

        if _params.get('as_at') is not None:  # noqa: E501
            if isinstance(_params['as_at'], datetime):
                _query_params.append(('asAt', _params['as_at'].strftime(self.api_client.configuration.datetime_format)))
            else:
                _query_params.append(('asAt', _params['as_at']))

        if _params.get('filter') is not None:  # noqa: E501
            _query_params.append(('filter', _params['filter']))

        if _params.get('identifier_types') is not None:  # noqa: E501
            _query_params.append(('identifierTypes', _params['identifier_types']))
            _collection_formats['identifierTypes'] = 'multi'

        # process the header parameters
        _header_params = dict(_params.get('_headers', {}))
        # process the form parameters
        _form_params = []
        _files = {}
        # process the body parameter
        _body_params = None
        # set the HTTP header `Accept`
        _header_params['Accept'] = self.api_client.select_header_accept(
            ['text/plain', 'application/json', 'text/json'])  # noqa: E501

        # authentication setting
        _auth_settings = ['oauth2']  # noqa: E501

        _response_types_map = {
            '200': "ResourceListOfRelation",
            '400': "LusidValidationProblemDetails",
        }

        return self.api_client.call_api(
            '/api/portfoliogroups/{scope}/{code}/relations', 'GET',
            _path_params,
            _query_params,
            _header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            response_types_map=_response_types_map,
            auth_settings=_auth_settings,
            async_req=_params.get('async_req'),
            _return_http_data_only=_params.get('_return_http_data_only'),  # noqa: E501
            _preload_content=_params.get('_preload_content', True),
            _request_timeout=_params.get('_request_timeout'),
            opts=_params.get('opts'),
            collection_formats=_collection_formats,
            _request_auth=_params.get('_request_auth'))


    @overload
    async def get_portfolio_group_relationships(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group. Together with the scope this uniquely identifies              the portfolio group.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label at which to retrieve relationship. Defaults to the current LUSID system datetime if not specified.")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to retrieve relationships. Defaults to return the latest LUSID AsAt time if not specified.")] = None, filter : Annotated[Optional[StrictStr], Field( description="Expression to filter relationships. Users should provide null or empty string for this field until further notice.")] = None, identifier_types : Annotated[Optional[List[StrictStr]], Field(description="Identifier types (as property keys) used for referencing Persons or Legal Entities.              These can be specified from the 'Person' or 'LegalEntity' domains and have the format {domain}/{scope}/{code}, for example              'Person/CompanyDetails/Role'. An Empty array may be used to return all related Entities.")] = None, **kwargs) -> ResourceListOfRelationship:  # noqa: E501
        ...

    @overload
    def get_portfolio_group_relationships(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group. Together with the scope this uniquely identifies              the portfolio group.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label at which to retrieve relationship. Defaults to the current LUSID system datetime if not specified.")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to retrieve relationships. Defaults to return the latest LUSID AsAt time if not specified.")] = None, filter : Annotated[Optional[StrictStr], Field( description="Expression to filter relationships. Users should provide null or empty string for this field until further notice.")] = None, identifier_types : Annotated[Optional[List[StrictStr]], Field(description="Identifier types (as property keys) used for referencing Persons or Legal Entities.              These can be specified from the 'Person' or 'LegalEntity' domains and have the format {domain}/{scope}/{code}, for example              'Person/CompanyDetails/Role'. An Empty array may be used to return all related Entities.")] = None, async_req: Optional[bool]=True, **kwargs) -> ResourceListOfRelationship:  # noqa: E501
        ...

    @validate_arguments
    def get_portfolio_group_relationships(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group. Together with the scope this uniquely identifies              the portfolio group.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label at which to retrieve relationship. Defaults to the current LUSID system datetime if not specified.")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to retrieve relationships. Defaults to return the latest LUSID AsAt time if not specified.")] = None, filter : Annotated[Optional[StrictStr], Field( description="Expression to filter relationships. Users should provide null or empty string for this field until further notice.")] = None, identifier_types : Annotated[Optional[List[StrictStr]], Field(description="Identifier types (as property keys) used for referencing Persons or Legal Entities.              These can be specified from the 'Person' or 'LegalEntity' domains and have the format {domain}/{scope}/{code}, for example              'Person/CompanyDetails/Role'. An Empty array may be used to return all related Entities.")] = None, async_req: Optional[bool]=None, **kwargs) -> Union[ResourceListOfRelationship, Awaitable[ResourceListOfRelationship]]:  # noqa: E501
        """[EARLY ACCESS] GetPortfolioGroupRelationships: Get Relationships for Portfolio Group  # noqa: E501

        Get relationships for the specified Portfolio Group  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.get_portfolio_group_relationships(scope, code, effective_at, as_at, filter, identifier_types, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the portfolio group. (required)
        :type scope: str
        :param code: The code of the portfolio group. Together with the scope this uniquely identifies              the portfolio group. (required)
        :type code: str
        :param effective_at: The effective datetime or cut label at which to retrieve relationship. Defaults to the current LUSID system datetime if not specified.
        :type effective_at: str
        :param as_at: The asAt datetime at which to retrieve relationships. Defaults to return the latest LUSID AsAt time if not specified.
        :type as_at: datetime
        :param filter: Expression to filter relationships. Users should provide null or empty string for this field until further notice.
        :type filter: str
        :param identifier_types: Identifier types (as property keys) used for referencing Persons or Legal Entities.              These can be specified from the 'Person' or 'LegalEntity' domains and have the format {domain}/{scope}/{code}, for example              'Person/CompanyDetails/Role'. An Empty array may be used to return all related Entities.
        :type identifier_types: List[str]
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: ResourceListOfRelationship
        """
        kwargs['_return_http_data_only'] = True
        if '_preload_content' in kwargs:
            message = "Error! Please call the get_portfolio_group_relationships_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data"  # noqa: E501
            raise ValueError(message)
        if async_req is not None:
            kwargs['async_req'] = async_req
        return self.get_portfolio_group_relationships_with_http_info(scope, code, effective_at, as_at, filter, identifier_types, **kwargs)  # noqa: E501

    @validate_arguments
    def get_portfolio_group_relationships_with_http_info(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group. Together with the scope this uniquely identifies              the portfolio group.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label at which to retrieve relationship. Defaults to the current LUSID system datetime if not specified.")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to retrieve relationships. Defaults to return the latest LUSID AsAt time if not specified.")] = None, filter : Annotated[Optional[StrictStr], Field( description="Expression to filter relationships. Users should provide null or empty string for this field until further notice.")] = None, identifier_types : Annotated[Optional[List[StrictStr]], Field(description="Identifier types (as property keys) used for referencing Persons or Legal Entities.              These can be specified from the 'Person' or 'LegalEntity' domains and have the format {domain}/{scope}/{code}, for example              'Person/CompanyDetails/Role'. An Empty array may be used to return all related Entities.")] = None, **kwargs) -> ApiResponse:  # noqa: E501
        """[EARLY ACCESS] GetPortfolioGroupRelationships: Get Relationships for Portfolio Group  # noqa: E501

        Get relationships for the specified Portfolio Group  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.get_portfolio_group_relationships_with_http_info(scope, code, effective_at, as_at, filter, identifier_types, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the portfolio group. (required)
        :type scope: str
        :param code: The code of the portfolio group. Together with the scope this uniquely identifies              the portfolio group. (required)
        :type code: str
        :param effective_at: The effective datetime or cut label at which to retrieve relationship. Defaults to the current LUSID system datetime if not specified.
        :type effective_at: str
        :param as_at: The asAt datetime at which to retrieve relationships. Defaults to return the latest LUSID AsAt time if not specified.
        :type as_at: datetime
        :param filter: Expression to filter relationships. Users should provide null or empty string for this field until further notice.
        :type filter: str
        :param identifier_types: Identifier types (as property keys) used for referencing Persons or Legal Entities.              These can be specified from the 'Person' or 'LegalEntity' domains and have the format {domain}/{scope}/{code}, for example              'Person/CompanyDetails/Role'. An Empty array may be used to return all related Entities.
        :type identifier_types: List[str]
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _preload_content: if False, the ApiResponse.data will
                                 be set to none and raw_data will store the
                                 HTTP response body without reading/decoding.
                                 Default is True.
        :type _preload_content: bool, optional
        :param _return_http_data_only: response data instead of ApiResponse
                                       object with status code, headers, etc
        :type _return_http_data_only: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the authentication
                              in the spec for a single request.
        :type _request_auth: dict, optional
        :type _content_type: string, optional: force content-type for the request
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: tuple(ResourceListOfRelationship, status_code(int), headers(HTTPHeaderDict))
        """

        _params = locals()

        _all_params = [
            'scope',
            'code',
            'effective_at',
            'as_at',
            'filter',
            'identifier_types'
        ]
        _all_params.extend(
            [
                'async_req',
                '_return_http_data_only',
                '_preload_content',
                '_request_timeout',
                '_request_auth',
                '_content_type',
                '_headers',
                'opts'
            ]
        )

        # validate the arguments
        for _key, _val in _params['kwargs'].items():
            if _key not in _all_params:
                raise ApiTypeError(
                    "Got an unexpected keyword argument '%s'"
                    " to method get_portfolio_group_relationships" % _key
                )
            _params[_key] = _val
        del _params['kwargs']

        _collection_formats = {}

        # process the path parameters
        _path_params = {}
        if _params['scope']:
            _path_params['scope'] = _params['scope']

        if _params['code']:
            _path_params['code'] = _params['code']


        # process the query parameters
        _query_params = []
        if _params.get('effective_at') is not None:  # noqa: E501
            _query_params.append(('effectiveAt', _params['effective_at']))

        if _params.get('as_at') is not None:  # noqa: E501
            if isinstance(_params['as_at'], datetime):
                _query_params.append(('asAt', _params['as_at'].strftime(self.api_client.configuration.datetime_format)))
            else:
                _query_params.append(('asAt', _params['as_at']))

        if _params.get('filter') is not None:  # noqa: E501
            _query_params.append(('filter', _params['filter']))

        if _params.get('identifier_types') is not None:  # noqa: E501
            _query_params.append(('identifierTypes', _params['identifier_types']))
            _collection_formats['identifierTypes'] = 'multi'

        # process the header parameters
        _header_params = dict(_params.get('_headers', {}))
        # process the form parameters
        _form_params = []
        _files = {}
        # process the body parameter
        _body_params = None
        # set the HTTP header `Accept`
        _header_params['Accept'] = self.api_client.select_header_accept(
            ['text/plain', 'application/json', 'text/json'])  # noqa: E501

        # authentication setting
        _auth_settings = ['oauth2']  # noqa: E501

        _response_types_map = {
            '200': "ResourceListOfRelationship",
            '400': "LusidValidationProblemDetails",
        }

        return self.api_client.call_api(
            '/api/portfoliogroups/{scope}/{code}/relationships', 'GET',
            _path_params,
            _query_params,
            _header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            response_types_map=_response_types_map,
            auth_settings=_auth_settings,
            async_req=_params.get('async_req'),
            _return_http_data_only=_params.get('_return_http_data_only'),  # noqa: E501
            _preload_content=_params.get('_preload_content', True),
            _request_timeout=_params.get('_request_timeout'),
            opts=_params.get('opts'),
            collection_formats=_collection_formats,
            _request_auth=_params.get('_request_auth'))


    @overload
    async def get_transactions_for_portfolio_group(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group. Together with the scope this uniquely identifies               the portfolio group.")], from_transaction_date : Annotated[Optional[StrictStr], Field( description="The lower bound effective datetime or cut label (inclusive) from which to retrieve the transactions.               There is no lower bound if this is not specified.")] = None, to_transaction_date : Annotated[Optional[StrictStr], Field( description="The upper bound effective datetime or cut label (inclusive) from which to retrieve transactions.               There is no upper bound if this is not specified.")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to retrieve the transactions. Defaults to return the latest version               of each transaction if not specified.")] = None, filter : Annotated[Optional[StrictStr], Field( description="Expression to filter the result set.               For example, to filter on the Transaction Type, use \"type eq 'Buy'\"               Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.")] = None, property_keys : Annotated[Optional[List[StrictStr]], Field(description="A list of property keys from the \"Instrument\", \"Transaction\", \"LegalEntity\" or \"CustodianAccount\" domain to decorate onto               the transactions. These take the format {domain}/{scope}/{code} e.g. \"Instrument/system/Name\" or               \"Transaction/strategy/quantsignal\".")] = None, limit : Annotated[Optional[StrictInt], Field(description="When paginating, limit the number of returned results to this many. Defaults to 100 if not specified.")] = None, page : Annotated[Optional[StrictStr], Field( description="The pagination token to use to continue listing transactions from a previous call to GetTransactions.")] = None, show_cancelled_transactions : Annotated[Optional[StrictBool], Field(description="Option to specify whether or not to include cancelled transactions,               including previous versions of transactions which have since been amended.               Defaults to False if not specified.")] = None, sort_by : Annotated[Optional[List[StrictStr]], Field(description="A list of field names or properties to sort by, each suffixed by \" ASC\" or \" DESC\".")] = None, data_model_scope : Annotated[Optional[StrictStr], Field( description="The optional scope of a Custom Data Model to use")] = None, data_model_code : Annotated[Optional[StrictStr], Field( description="The optional code of a Custom Data Model to use")] = None, membership_type : Annotated[Optional[StrictStr], Field( description="The membership types of the specified Custom Data Model to return. Allowable values are Member, Candidate and All. Defaults to Member.")] = None, **kwargs) -> VersionedResourceListOfTransaction:  # noqa: E501
        ...

    @overload
    def get_transactions_for_portfolio_group(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group. Together with the scope this uniquely identifies               the portfolio group.")], from_transaction_date : Annotated[Optional[StrictStr], Field( description="The lower bound effective datetime or cut label (inclusive) from which to retrieve the transactions.               There is no lower bound if this is not specified.")] = None, to_transaction_date : Annotated[Optional[StrictStr], Field( description="The upper bound effective datetime or cut label (inclusive) from which to retrieve transactions.               There is no upper bound if this is not specified.")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to retrieve the transactions. Defaults to return the latest version               of each transaction if not specified.")] = None, filter : Annotated[Optional[StrictStr], Field( description="Expression to filter the result set.               For example, to filter on the Transaction Type, use \"type eq 'Buy'\"               Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.")] = None, property_keys : Annotated[Optional[List[StrictStr]], Field(description="A list of property keys from the \"Instrument\", \"Transaction\", \"LegalEntity\" or \"CustodianAccount\" domain to decorate onto               the transactions. These take the format {domain}/{scope}/{code} e.g. \"Instrument/system/Name\" or               \"Transaction/strategy/quantsignal\".")] = None, limit : Annotated[Optional[StrictInt], Field(description="When paginating, limit the number of returned results to this many. Defaults to 100 if not specified.")] = None, page : Annotated[Optional[StrictStr], Field( description="The pagination token to use to continue listing transactions from a previous call to GetTransactions.")] = None, show_cancelled_transactions : Annotated[Optional[StrictBool], Field(description="Option to specify whether or not to include cancelled transactions,               including previous versions of transactions which have since been amended.               Defaults to False if not specified.")] = None, sort_by : Annotated[Optional[List[StrictStr]], Field(description="A list of field names or properties to sort by, each suffixed by \" ASC\" or \" DESC\".")] = None, data_model_scope : Annotated[Optional[StrictStr], Field( description="The optional scope of a Custom Data Model to use")] = None, data_model_code : Annotated[Optional[StrictStr], Field( description="The optional code of a Custom Data Model to use")] = None, membership_type : Annotated[Optional[StrictStr], Field( description="The membership types of the specified Custom Data Model to return. Allowable values are Member, Candidate and All. Defaults to Member.")] = None, async_req: Optional[bool]=True, **kwargs) -> VersionedResourceListOfTransaction:  # noqa: E501
        ...

    @validate_arguments
    def get_transactions_for_portfolio_group(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group. Together with the scope this uniquely identifies               the portfolio group.")], from_transaction_date : Annotated[Optional[StrictStr], Field( description="The lower bound effective datetime or cut label (inclusive) from which to retrieve the transactions.               There is no lower bound if this is not specified.")] = None, to_transaction_date : Annotated[Optional[StrictStr], Field( description="The upper bound effective datetime or cut label (inclusive) from which to retrieve transactions.               There is no upper bound if this is not specified.")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to retrieve the transactions. Defaults to return the latest version               of each transaction if not specified.")] = None, filter : Annotated[Optional[StrictStr], Field( description="Expression to filter the result set.               For example, to filter on the Transaction Type, use \"type eq 'Buy'\"               Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.")] = None, property_keys : Annotated[Optional[List[StrictStr]], Field(description="A list of property keys from the \"Instrument\", \"Transaction\", \"LegalEntity\" or \"CustodianAccount\" domain to decorate onto               the transactions. These take the format {domain}/{scope}/{code} e.g. \"Instrument/system/Name\" or               \"Transaction/strategy/quantsignal\".")] = None, limit : Annotated[Optional[StrictInt], Field(description="When paginating, limit the number of returned results to this many. Defaults to 100 if not specified.")] = None, page : Annotated[Optional[StrictStr], Field( description="The pagination token to use to continue listing transactions from a previous call to GetTransactions.")] = None, show_cancelled_transactions : Annotated[Optional[StrictBool], Field(description="Option to specify whether or not to include cancelled transactions,               including previous versions of transactions which have since been amended.               Defaults to False if not specified.")] = None, sort_by : Annotated[Optional[List[StrictStr]], Field(description="A list of field names or properties to sort by, each suffixed by \" ASC\" or \" DESC\".")] = None, data_model_scope : Annotated[Optional[StrictStr], Field( description="The optional scope of a Custom Data Model to use")] = None, data_model_code : Annotated[Optional[StrictStr], Field( description="The optional code of a Custom Data Model to use")] = None, membership_type : Annotated[Optional[StrictStr], Field( description="The membership types of the specified Custom Data Model to return. Allowable values are Member, Candidate and All. Defaults to Member.")] = None, async_req: Optional[bool]=None, **kwargs) -> Union[VersionedResourceListOfTransaction, Awaitable[VersionedResourceListOfTransaction]]:  # noqa: E501
        """GetTransactionsForPortfolioGroup: Get transactions for transaction portfolios in a portfolio group  # noqa: E501

        Get transactions for transaction portfolios in a portfolio group over a given interval of effective time.                When the specified portfolio in a portfolio group is a derived transaction portfolio, the returned set of transactions is the  union set of all transactions of the parent (and any grandparents etc.) and the specified derived transaction portfolio itself.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.get_transactions_for_portfolio_group(scope, code, from_transaction_date, to_transaction_date, as_at, filter, property_keys, limit, page, show_cancelled_transactions, sort_by, data_model_scope, data_model_code, membership_type, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the portfolio group. (required)
        :type scope: str
        :param code: The code of the portfolio group. Together with the scope this uniquely identifies               the portfolio group. (required)
        :type code: str
        :param from_transaction_date: The lower bound effective datetime or cut label (inclusive) from which to retrieve the transactions.               There is no lower bound if this is not specified.
        :type from_transaction_date: str
        :param to_transaction_date: The upper bound effective datetime or cut label (inclusive) from which to retrieve transactions.               There is no upper bound if this is not specified.
        :type to_transaction_date: str
        :param as_at: The asAt datetime at which to retrieve the transactions. Defaults to return the latest version               of each transaction if not specified.
        :type as_at: datetime
        :param filter: Expression to filter the result set.               For example, to filter on the Transaction Type, use \"type eq 'Buy'\"               Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.
        :type filter: str
        :param property_keys: A list of property keys from the \"Instrument\", \"Transaction\", \"LegalEntity\" or \"CustodianAccount\" domain to decorate onto               the transactions. These take the format {domain}/{scope}/{code} e.g. \"Instrument/system/Name\" or               \"Transaction/strategy/quantsignal\".
        :type property_keys: List[str]
        :param limit: When paginating, limit the number of returned results to this many. Defaults to 100 if not specified.
        :type limit: int
        :param page: The pagination token to use to continue listing transactions from a previous call to GetTransactions.
        :type page: str
        :param show_cancelled_transactions: Option to specify whether or not to include cancelled transactions,               including previous versions of transactions which have since been amended.               Defaults to False if not specified.
        :type show_cancelled_transactions: bool
        :param sort_by: A list of field names or properties to sort by, each suffixed by \" ASC\" or \" DESC\".
        :type sort_by: List[str]
        :param data_model_scope: The optional scope of a Custom Data Model to use
        :type data_model_scope: str
        :param data_model_code: The optional code of a Custom Data Model to use
        :type data_model_code: str
        :param membership_type: The membership types of the specified Custom Data Model to return. Allowable values are Member, Candidate and All. Defaults to Member.
        :type membership_type: str
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: VersionedResourceListOfTransaction
        """
        kwargs['_return_http_data_only'] = True
        if '_preload_content' in kwargs:
            message = "Error! Please call the get_transactions_for_portfolio_group_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data"  # noqa: E501
            raise ValueError(message)
        if async_req is not None:
            kwargs['async_req'] = async_req
        return self.get_transactions_for_portfolio_group_with_http_info(scope, code, from_transaction_date, to_transaction_date, as_at, filter, property_keys, limit, page, show_cancelled_transactions, sort_by, data_model_scope, data_model_code, membership_type, **kwargs)  # noqa: E501

    @validate_arguments
    def get_transactions_for_portfolio_group_with_http_info(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group. Together with the scope this uniquely identifies               the portfolio group.")], from_transaction_date : Annotated[Optional[StrictStr], Field( description="The lower bound effective datetime or cut label (inclusive) from which to retrieve the transactions.               There is no lower bound if this is not specified.")] = None, to_transaction_date : Annotated[Optional[StrictStr], Field( description="The upper bound effective datetime or cut label (inclusive) from which to retrieve transactions.               There is no upper bound if this is not specified.")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to retrieve the transactions. Defaults to return the latest version               of each transaction if not specified.")] = None, filter : Annotated[Optional[StrictStr], Field( description="Expression to filter the result set.               For example, to filter on the Transaction Type, use \"type eq 'Buy'\"               Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.")] = None, property_keys : Annotated[Optional[List[StrictStr]], Field(description="A list of property keys from the \"Instrument\", \"Transaction\", \"LegalEntity\" or \"CustodianAccount\" domain to decorate onto               the transactions. These take the format {domain}/{scope}/{code} e.g. \"Instrument/system/Name\" or               \"Transaction/strategy/quantsignal\".")] = None, limit : Annotated[Optional[StrictInt], Field(description="When paginating, limit the number of returned results to this many. Defaults to 100 if not specified.")] = None, page : Annotated[Optional[StrictStr], Field( description="The pagination token to use to continue listing transactions from a previous call to GetTransactions.")] = None, show_cancelled_transactions : Annotated[Optional[StrictBool], Field(description="Option to specify whether or not to include cancelled transactions,               including previous versions of transactions which have since been amended.               Defaults to False if not specified.")] = None, sort_by : Annotated[Optional[List[StrictStr]], Field(description="A list of field names or properties to sort by, each suffixed by \" ASC\" or \" DESC\".")] = None, data_model_scope : Annotated[Optional[StrictStr], Field( description="The optional scope of a Custom Data Model to use")] = None, data_model_code : Annotated[Optional[StrictStr], Field( description="The optional code of a Custom Data Model to use")] = None, membership_type : Annotated[Optional[StrictStr], Field( description="The membership types of the specified Custom Data Model to return. Allowable values are Member, Candidate and All. Defaults to Member.")] = None, **kwargs) -> ApiResponse:  # noqa: E501
        """GetTransactionsForPortfolioGroup: Get transactions for transaction portfolios in a portfolio group  # noqa: E501

        Get transactions for transaction portfolios in a portfolio group over a given interval of effective time.                When the specified portfolio in a portfolio group is a derived transaction portfolio, the returned set of transactions is the  union set of all transactions of the parent (and any grandparents etc.) and the specified derived transaction portfolio itself.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.get_transactions_for_portfolio_group_with_http_info(scope, code, from_transaction_date, to_transaction_date, as_at, filter, property_keys, limit, page, show_cancelled_transactions, sort_by, data_model_scope, data_model_code, membership_type, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the portfolio group. (required)
        :type scope: str
        :param code: The code of the portfolio group. Together with the scope this uniquely identifies               the portfolio group. (required)
        :type code: str
        :param from_transaction_date: The lower bound effective datetime or cut label (inclusive) from which to retrieve the transactions.               There is no lower bound if this is not specified.
        :type from_transaction_date: str
        :param to_transaction_date: The upper bound effective datetime or cut label (inclusive) from which to retrieve transactions.               There is no upper bound if this is not specified.
        :type to_transaction_date: str
        :param as_at: The asAt datetime at which to retrieve the transactions. Defaults to return the latest version               of each transaction if not specified.
        :type as_at: datetime
        :param filter: Expression to filter the result set.               For example, to filter on the Transaction Type, use \"type eq 'Buy'\"               Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.
        :type filter: str
        :param property_keys: A list of property keys from the \"Instrument\", \"Transaction\", \"LegalEntity\" or \"CustodianAccount\" domain to decorate onto               the transactions. These take the format {domain}/{scope}/{code} e.g. \"Instrument/system/Name\" or               \"Transaction/strategy/quantsignal\".
        :type property_keys: List[str]
        :param limit: When paginating, limit the number of returned results to this many. Defaults to 100 if not specified.
        :type limit: int
        :param page: The pagination token to use to continue listing transactions from a previous call to GetTransactions.
        :type page: str
        :param show_cancelled_transactions: Option to specify whether or not to include cancelled transactions,               including previous versions of transactions which have since been amended.               Defaults to False if not specified.
        :type show_cancelled_transactions: bool
        :param sort_by: A list of field names or properties to sort by, each suffixed by \" ASC\" or \" DESC\".
        :type sort_by: List[str]
        :param data_model_scope: The optional scope of a Custom Data Model to use
        :type data_model_scope: str
        :param data_model_code: The optional code of a Custom Data Model to use
        :type data_model_code: str
        :param membership_type: The membership types of the specified Custom Data Model to return. Allowable values are Member, Candidate and All. Defaults to Member.
        :type membership_type: str
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _preload_content: if False, the ApiResponse.data will
                                 be set to none and raw_data will store the
                                 HTTP response body without reading/decoding.
                                 Default is True.
        :type _preload_content: bool, optional
        :param _return_http_data_only: response data instead of ApiResponse
                                       object with status code, headers, etc
        :type _return_http_data_only: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the authentication
                              in the spec for a single request.
        :type _request_auth: dict, optional
        :type _content_type: string, optional: force content-type for the request
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: tuple(VersionedResourceListOfTransaction, status_code(int), headers(HTTPHeaderDict))
        """

        _params = locals()

        _all_params = [
            'scope',
            'code',
            'from_transaction_date',
            'to_transaction_date',
            'as_at',
            'filter',
            'property_keys',
            'limit',
            'page',
            'show_cancelled_transactions',
            'sort_by',
            'data_model_scope',
            'data_model_code',
            'membership_type'
        ]
        _all_params.extend(
            [
                'async_req',
                '_return_http_data_only',
                '_preload_content',
                '_request_timeout',
                '_request_auth',
                '_content_type',
                '_headers',
                'opts'
            ]
        )

        # validate the arguments
        for _key, _val in _params['kwargs'].items():
            if _key not in _all_params:
                raise ApiTypeError(
                    "Got an unexpected keyword argument '%s'"
                    " to method get_transactions_for_portfolio_group" % _key
                )
            _params[_key] = _val
        del _params['kwargs']

        _collection_formats = {}

        # process the path parameters
        _path_params = {}
        if _params['scope']:
            _path_params['scope'] = _params['scope']

        if _params['code']:
            _path_params['code'] = _params['code']


        # process the query parameters
        _query_params = []
        if _params.get('from_transaction_date') is not None:  # noqa: E501
            _query_params.append(('fromTransactionDate', _params['from_transaction_date']))

        if _params.get('to_transaction_date') is not None:  # noqa: E501
            _query_params.append(('toTransactionDate', _params['to_transaction_date']))

        if _params.get('as_at') is not None:  # noqa: E501
            if isinstance(_params['as_at'], datetime):
                _query_params.append(('asAt', _params['as_at'].strftime(self.api_client.configuration.datetime_format)))
            else:
                _query_params.append(('asAt', _params['as_at']))

        if _params.get('filter') is not None:  # noqa: E501
            _query_params.append(('filter', _params['filter']))

        if _params.get('property_keys') is not None:  # noqa: E501
            _query_params.append(('propertyKeys', _params['property_keys']))
            _collection_formats['propertyKeys'] = 'multi'

        if _params.get('limit') is not None:  # noqa: E501
            _query_params.append(('limit', _params['limit']))

        if _params.get('page') is not None:  # noqa: E501
            _query_params.append(('page', _params['page']))

        if _params.get('show_cancelled_transactions') is not None:  # noqa: E501
            _query_params.append(('showCancelledTransactions', _params['show_cancelled_transactions']))

        if _params.get('sort_by') is not None:  # noqa: E501
            _query_params.append(('sortBy', _params['sort_by']))
            _collection_formats['sortBy'] = 'multi'

        if _params.get('data_model_scope') is not None:  # noqa: E501
            _query_params.append(('dataModelScope', _params['data_model_scope']))

        if _params.get('data_model_code') is not None:  # noqa: E501
            _query_params.append(('dataModelCode', _params['data_model_code']))

        if _params.get('membership_type') is not None:  # noqa: E501
            _query_params.append(('membershipType', _params['membership_type']))

        # process the header parameters
        _header_params = dict(_params.get('_headers', {}))
        # process the form parameters
        _form_params = []
        _files = {}
        # process the body parameter
        _body_params = None
        # set the HTTP header `Accept`
        _header_params['Accept'] = self.api_client.select_header_accept(
            ['text/plain', 'application/json', 'text/json'])  # noqa: E501

        # authentication setting
        _auth_settings = ['oauth2']  # noqa: E501

        _response_types_map = {
            '200': "VersionedResourceListOfTransaction",
            '400': "LusidValidationProblemDetails",
        }

        return self.api_client.call_api(
            '/api/portfoliogroups/{scope}/{code}/transactions', 'GET',
            _path_params,
            _query_params,
            _header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            response_types_map=_response_types_map,
            auth_settings=_auth_settings,
            async_req=_params.get('async_req'),
            _return_http_data_only=_params.get('_return_http_data_only'),  # noqa: E501
            _preload_content=_params.get('_preload_content', True),
            _request_timeout=_params.get('_request_timeout'),
            opts=_params.get('opts'),
            collection_formats=_collection_formats,
            _request_auth=_params.get('_request_auth'))


    @overload
    async def list_portfolio_groups(self, scope : Annotated[StrictStr, Field(..., description="The scope to list the portfolio groups in.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label at which to list the portfolio groups. Defaults to the current LUSID system datetime if not specified.")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to list the portfolio groups. Defaults to return the latest version of each portfolio group if not specified.")] = None, page : Annotated[Optional[StrictStr], Field( description="The pagination token to use to continue listing portfolio groups from a previous call to list portfolio groups. This  value is returned from the previous call. If a pagination token is provided the filter, effectiveAt, sortBy  and asAt fields must not have changed since the original request.")] = None, limit : Annotated[Optional[StrictInt], Field(description="When paginating, limit the number of returned results to this many. Defaults to no limit if not specified.")] = None, filter : Annotated[Optional[StrictStr], Field( description="Expression to filter the result set.              For example, to filter on the Display Name, use \"displayName eq 'string'\"              Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.")] = None, sort_by : Annotated[Optional[List[StrictStr]], Field(description="A list of field names to sort by, each suffixed by \" ASC\" or \" DESC\"")] = None, related_entity_property_keys : Annotated[Optional[List[StrictStr]], Field(description="A list of property keys from any domain that supports relationships              to decorate onto related entities. These must take the format {domain}/{scope}/{code}, for example 'Portfolio/Manager/Id'.")] = None, relationship_definition_ids : Annotated[Optional[List[StrictStr]], Field(description="A list of relationship definitions that are used to decorate related entities              onto the portfolio groups in the response. These must take the form {relationshipDefinitionScope}/{relationshipDefinitionCode}.")] = None, **kwargs) -> PagedResourceListOfPortfolioGroup:  # noqa: E501
        ...

    @overload
    def list_portfolio_groups(self, scope : Annotated[StrictStr, Field(..., description="The scope to list the portfolio groups in.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label at which to list the portfolio groups. Defaults to the current LUSID system datetime if not specified.")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to list the portfolio groups. Defaults to return the latest version of each portfolio group if not specified.")] = None, page : Annotated[Optional[StrictStr], Field( description="The pagination token to use to continue listing portfolio groups from a previous call to list portfolio groups. This  value is returned from the previous call. If a pagination token is provided the filter, effectiveAt, sortBy  and asAt fields must not have changed since the original request.")] = None, limit : Annotated[Optional[StrictInt], Field(description="When paginating, limit the number of returned results to this many. Defaults to no limit if not specified.")] = None, filter : Annotated[Optional[StrictStr], Field( description="Expression to filter the result set.              For example, to filter on the Display Name, use \"displayName eq 'string'\"              Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.")] = None, sort_by : Annotated[Optional[List[StrictStr]], Field(description="A list of field names to sort by, each suffixed by \" ASC\" or \" DESC\"")] = None, related_entity_property_keys : Annotated[Optional[List[StrictStr]], Field(description="A list of property keys from any domain that supports relationships              to decorate onto related entities. These must take the format {domain}/{scope}/{code}, for example 'Portfolio/Manager/Id'.")] = None, relationship_definition_ids : Annotated[Optional[List[StrictStr]], Field(description="A list of relationship definitions that are used to decorate related entities              onto the portfolio groups in the response. These must take the form {relationshipDefinitionScope}/{relationshipDefinitionCode}.")] = None, async_req: Optional[bool]=True, **kwargs) -> PagedResourceListOfPortfolioGroup:  # noqa: E501
        ...

    @validate_arguments
    def list_portfolio_groups(self, scope : Annotated[StrictStr, Field(..., description="The scope to list the portfolio groups in.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label at which to list the portfolio groups. Defaults to the current LUSID system datetime if not specified.")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to list the portfolio groups. Defaults to return the latest version of each portfolio group if not specified.")] = None, page : Annotated[Optional[StrictStr], Field( description="The pagination token to use to continue listing portfolio groups from a previous call to list portfolio groups. This  value is returned from the previous call. If a pagination token is provided the filter, effectiveAt, sortBy  and asAt fields must not have changed since the original request.")] = None, limit : Annotated[Optional[StrictInt], Field(description="When paginating, limit the number of returned results to this many. Defaults to no limit if not specified.")] = None, filter : Annotated[Optional[StrictStr], Field( description="Expression to filter the result set.              For example, to filter on the Display Name, use \"displayName eq 'string'\"              Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.")] = None, sort_by : Annotated[Optional[List[StrictStr]], Field(description="A list of field names to sort by, each suffixed by \" ASC\" or \" DESC\"")] = None, related_entity_property_keys : Annotated[Optional[List[StrictStr]], Field(description="A list of property keys from any domain that supports relationships              to decorate onto related entities. These must take the format {domain}/{scope}/{code}, for example 'Portfolio/Manager/Id'.")] = None, relationship_definition_ids : Annotated[Optional[List[StrictStr]], Field(description="A list of relationship definitions that are used to decorate related entities              onto the portfolio groups in the response. These must take the form {relationshipDefinitionScope}/{relationshipDefinitionCode}.")] = None, async_req: Optional[bool]=None, **kwargs) -> Union[PagedResourceListOfPortfolioGroup, Awaitable[PagedResourceListOfPortfolioGroup]]:  # noqa: E501
        """ListPortfolioGroups: List portfolio groups  # noqa: E501

        List all the portfolio groups in a single scope.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.list_portfolio_groups(scope, effective_at, as_at, page, limit, filter, sort_by, related_entity_property_keys, relationship_definition_ids, async_req=True)
        >>> result = thread.get()

        :param scope: The scope to list the portfolio groups in. (required)
        :type scope: str
        :param effective_at: The effective datetime or cut label at which to list the portfolio groups. Defaults to the current LUSID system datetime if not specified.
        :type effective_at: str
        :param as_at: The asAt datetime at which to list the portfolio groups. Defaults to return the latest version of each portfolio group if not specified.
        :type as_at: datetime
        :param page: The pagination token to use to continue listing portfolio groups from a previous call to list portfolio groups. This  value is returned from the previous call. If a pagination token is provided the filter, effectiveAt, sortBy  and asAt fields must not have changed since the original request.
        :type page: str
        :param limit: When paginating, limit the number of returned results to this many. Defaults to no limit if not specified.
        :type limit: int
        :param filter: Expression to filter the result set.              For example, to filter on the Display Name, use \"displayName eq 'string'\"              Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.
        :type filter: str
        :param sort_by: A list of field names to sort by, each suffixed by \" ASC\" or \" DESC\"
        :type sort_by: List[str]
        :param related_entity_property_keys: A list of property keys from any domain that supports relationships              to decorate onto related entities. These must take the format {domain}/{scope}/{code}, for example 'Portfolio/Manager/Id'.
        :type related_entity_property_keys: List[str]
        :param relationship_definition_ids: A list of relationship definitions that are used to decorate related entities              onto the portfolio groups in the response. These must take the form {relationshipDefinitionScope}/{relationshipDefinitionCode}.
        :type relationship_definition_ids: List[str]
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: PagedResourceListOfPortfolioGroup
        """
        kwargs['_return_http_data_only'] = True
        if '_preload_content' in kwargs:
            message = "Error! Please call the list_portfolio_groups_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data"  # noqa: E501
            raise ValueError(message)
        if async_req is not None:
            kwargs['async_req'] = async_req
        return self.list_portfolio_groups_with_http_info(scope, effective_at, as_at, page, limit, filter, sort_by, related_entity_property_keys, relationship_definition_ids, **kwargs)  # noqa: E501

    @validate_arguments
    def list_portfolio_groups_with_http_info(self, scope : Annotated[StrictStr, Field(..., description="The scope to list the portfolio groups in.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label at which to list the portfolio groups. Defaults to the current LUSID system datetime if not specified.")] = None, as_at : Annotated[Optional[datetime], Field(description="The asAt datetime at which to list the portfolio groups. Defaults to return the latest version of each portfolio group if not specified.")] = None, page : Annotated[Optional[StrictStr], Field( description="The pagination token to use to continue listing portfolio groups from a previous call to list portfolio groups. This  value is returned from the previous call. If a pagination token is provided the filter, effectiveAt, sortBy  and asAt fields must not have changed since the original request.")] = None, limit : Annotated[Optional[StrictInt], Field(description="When paginating, limit the number of returned results to this many. Defaults to no limit if not specified.")] = None, filter : Annotated[Optional[StrictStr], Field( description="Expression to filter the result set.              For example, to filter on the Display Name, use \"displayName eq 'string'\"              Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.")] = None, sort_by : Annotated[Optional[List[StrictStr]], Field(description="A list of field names to sort by, each suffixed by \" ASC\" or \" DESC\"")] = None, related_entity_property_keys : Annotated[Optional[List[StrictStr]], Field(description="A list of property keys from any domain that supports relationships              to decorate onto related entities. These must take the format {domain}/{scope}/{code}, for example 'Portfolio/Manager/Id'.")] = None, relationship_definition_ids : Annotated[Optional[List[StrictStr]], Field(description="A list of relationship definitions that are used to decorate related entities              onto the portfolio groups in the response. These must take the form {relationshipDefinitionScope}/{relationshipDefinitionCode}.")] = None, **kwargs) -> ApiResponse:  # noqa: E501
        """ListPortfolioGroups: List portfolio groups  # noqa: E501

        List all the portfolio groups in a single scope.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.list_portfolio_groups_with_http_info(scope, effective_at, as_at, page, limit, filter, sort_by, related_entity_property_keys, relationship_definition_ids, async_req=True)
        >>> result = thread.get()

        :param scope: The scope to list the portfolio groups in. (required)
        :type scope: str
        :param effective_at: The effective datetime or cut label at which to list the portfolio groups. Defaults to the current LUSID system datetime if not specified.
        :type effective_at: str
        :param as_at: The asAt datetime at which to list the portfolio groups. Defaults to return the latest version of each portfolio group if not specified.
        :type as_at: datetime
        :param page: The pagination token to use to continue listing portfolio groups from a previous call to list portfolio groups. This  value is returned from the previous call. If a pagination token is provided the filter, effectiveAt, sortBy  and asAt fields must not have changed since the original request.
        :type page: str
        :param limit: When paginating, limit the number of returned results to this many. Defaults to no limit if not specified.
        :type limit: int
        :param filter: Expression to filter the result set.              For example, to filter on the Display Name, use \"displayName eq 'string'\"              Read more about filtering results from LUSID here https://support.lusid.com/filtering-results-from-lusid.
        :type filter: str
        :param sort_by: A list of field names to sort by, each suffixed by \" ASC\" or \" DESC\"
        :type sort_by: List[str]
        :param related_entity_property_keys: A list of property keys from any domain that supports relationships              to decorate onto related entities. These must take the format {domain}/{scope}/{code}, for example 'Portfolio/Manager/Id'.
        :type related_entity_property_keys: List[str]
        :param relationship_definition_ids: A list of relationship definitions that are used to decorate related entities              onto the portfolio groups in the response. These must take the form {relationshipDefinitionScope}/{relationshipDefinitionCode}.
        :type relationship_definition_ids: List[str]
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _preload_content: if False, the ApiResponse.data will
                                 be set to none and raw_data will store the
                                 HTTP response body without reading/decoding.
                                 Default is True.
        :type _preload_content: bool, optional
        :param _return_http_data_only: response data instead of ApiResponse
                                       object with status code, headers, etc
        :type _return_http_data_only: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the authentication
                              in the spec for a single request.
        :type _request_auth: dict, optional
        :type _content_type: string, optional: force content-type for the request
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: tuple(PagedResourceListOfPortfolioGroup, status_code(int), headers(HTTPHeaderDict))
        """

        _params = locals()

        _all_params = [
            'scope',
            'effective_at',
            'as_at',
            'page',
            'limit',
            'filter',
            'sort_by',
            'related_entity_property_keys',
            'relationship_definition_ids'
        ]
        _all_params.extend(
            [
                'async_req',
                '_return_http_data_only',
                '_preload_content',
                '_request_timeout',
                '_request_auth',
                '_content_type',
                '_headers',
                'opts'
            ]
        )

        # validate the arguments
        for _key, _val in _params['kwargs'].items():
            if _key not in _all_params:
                raise ApiTypeError(
                    "Got an unexpected keyword argument '%s'"
                    " to method list_portfolio_groups" % _key
                )
            _params[_key] = _val
        del _params['kwargs']

        _collection_formats = {}

        # process the path parameters
        _path_params = {}
        if _params['scope']:
            _path_params['scope'] = _params['scope']


        # process the query parameters
        _query_params = []
        if _params.get('effective_at') is not None:  # noqa: E501
            _query_params.append(('effectiveAt', _params['effective_at']))

        if _params.get('as_at') is not None:  # noqa: E501
            if isinstance(_params['as_at'], datetime):
                _query_params.append(('asAt', _params['as_at'].strftime(self.api_client.configuration.datetime_format)))
            else:
                _query_params.append(('asAt', _params['as_at']))

        if _params.get('page') is not None:  # noqa: E501
            _query_params.append(('page', _params['page']))

        if _params.get('limit') is not None:  # noqa: E501
            _query_params.append(('limit', _params['limit']))

        if _params.get('filter') is not None:  # noqa: E501
            _query_params.append(('filter', _params['filter']))

        if _params.get('sort_by') is not None:  # noqa: E501
            _query_params.append(('sortBy', _params['sort_by']))
            _collection_formats['sortBy'] = 'multi'

        if _params.get('related_entity_property_keys') is not None:  # noqa: E501
            _query_params.append(('relatedEntityPropertyKeys', _params['related_entity_property_keys']))
            _collection_formats['relatedEntityPropertyKeys'] = 'multi'

        if _params.get('relationship_definition_ids') is not None:  # noqa: E501
            _query_params.append(('relationshipDefinitionIds', _params['relationship_definition_ids']))
            _collection_formats['relationshipDefinitionIds'] = 'multi'

        # process the header parameters
        _header_params = dict(_params.get('_headers', {}))
        # process the form parameters
        _form_params = []
        _files = {}
        # process the body parameter
        _body_params = None
        # set the HTTP header `Accept`
        _header_params['Accept'] = self.api_client.select_header_accept(
            ['text/plain', 'application/json', 'text/json'])  # noqa: E501

        # authentication setting
        _auth_settings = ['oauth2']  # noqa: E501

        _response_types_map = {
            '200': "PagedResourceListOfPortfolioGroup",
            '400': "LusidValidationProblemDetails",
        }

        return self.api_client.call_api(
            '/api/portfoliogroups/{scope}', 'GET',
            _path_params,
            _query_params,
            _header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            response_types_map=_response_types_map,
            auth_settings=_auth_settings,
            async_req=_params.get('async_req'),
            _return_http_data_only=_params.get('_return_http_data_only'),  # noqa: E501
            _preload_content=_params.get('_preload_content', True),
            _request_timeout=_params.get('_request_timeout'),
            opts=_params.get('opts'),
            collection_formats=_collection_formats,
            _request_auth=_params.get('_request_auth'))


    @overload
    async def patch_portfolio_group_access_metadata(self, scope : Annotated[StrictStr, Field(..., description="The scope of the Portfolio Group")], code : Annotated[StrictStr, Field(..., description="The Portfolio Group code")], access_metadata_operation : Annotated[List[AccessMetadataOperation], Field(description="The Json patch document")], effective_at : Annotated[Optional[StrictStr], Field( description="The date this rule will be effective from")] = None, effective_until : Annotated[Optional[datetime], Field(description="The effective date until which the Access Metadata is valid. If not supplied this will be valid indefinitely, or until the next 'effectiveAt' date of the Access Metadata")] = None, **kwargs) -> Dict[str, List[AccessMetadataValue]]:  # noqa: E501
        ...

    @overload
    def patch_portfolio_group_access_metadata(self, scope : Annotated[StrictStr, Field(..., description="The scope of the Portfolio Group")], code : Annotated[StrictStr, Field(..., description="The Portfolio Group code")], access_metadata_operation : Annotated[List[AccessMetadataOperation], Field(description="The Json patch document")], effective_at : Annotated[Optional[StrictStr], Field( description="The date this rule will be effective from")] = None, effective_until : Annotated[Optional[datetime], Field(description="The effective date until which the Access Metadata is valid. If not supplied this will be valid indefinitely, or until the next 'effectiveAt' date of the Access Metadata")] = None, async_req: Optional[bool]=True, **kwargs) -> Dict[str, List[AccessMetadataValue]]:  # noqa: E501
        ...

    @validate_arguments
    def patch_portfolio_group_access_metadata(self, scope : Annotated[StrictStr, Field(..., description="The scope of the Portfolio Group")], code : Annotated[StrictStr, Field(..., description="The Portfolio Group code")], access_metadata_operation : Annotated[List[AccessMetadataOperation], Field(description="The Json patch document")], effective_at : Annotated[Optional[StrictStr], Field( description="The date this rule will be effective from")] = None, effective_until : Annotated[Optional[datetime], Field(description="The effective date until which the Access Metadata is valid. If not supplied this will be valid indefinitely, or until the next 'effectiveAt' date of the Access Metadata")] = None, async_req: Optional[bool]=None, **kwargs) -> Union[Dict[str, List[AccessMetadataValue]], Awaitable[Dict[str, List[AccessMetadataValue]]]]:  # noqa: E501
        """[EARLY ACCESS] PatchPortfolioGroupAccessMetadata: Patch Access Metadata rules for a Portfolio Group.  # noqa: E501

        Patch Portfolio Group Access Metadata Rules in a single scope.  The behaviour is defined by the JSON Patch specification.                Currently only 'add' is a supported operation on the patch document.    Currently only valid metadata keys are supported paths on the patch document.                The response will return any affected Portfolio Group Access Metadata rules or a failure message if unsuccessful.                It is important to always check to verify success (or failure).                Multiple rules for a metadataKey can exist with different effective at dates, when resources are accessed the rule that is active for the current time will be fetched.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.patch_portfolio_group_access_metadata(scope, code, access_metadata_operation, effective_at, effective_until, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the Portfolio Group (required)
        :type scope: str
        :param code: The Portfolio Group code (required)
        :type code: str
        :param access_metadata_operation: The Json patch document (required)
        :type access_metadata_operation: List[AccessMetadataOperation]
        :param effective_at: The date this rule will be effective from
        :type effective_at: str
        :param effective_until: The effective date until which the Access Metadata is valid. If not supplied this will be valid indefinitely, or until the next 'effectiveAt' date of the Access Metadata
        :type effective_until: datetime
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: Dict[str, List[AccessMetadataValue]]
        """
        kwargs['_return_http_data_only'] = True
        if '_preload_content' in kwargs:
            message = "Error! Please call the patch_portfolio_group_access_metadata_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data"  # noqa: E501
            raise ValueError(message)
        if async_req is not None:
            kwargs['async_req'] = async_req
        return self.patch_portfolio_group_access_metadata_with_http_info(scope, code, access_metadata_operation, effective_at, effective_until, **kwargs)  # noqa: E501

    @validate_arguments
    def patch_portfolio_group_access_metadata_with_http_info(self, scope : Annotated[StrictStr, Field(..., description="The scope of the Portfolio Group")], code : Annotated[StrictStr, Field(..., description="The Portfolio Group code")], access_metadata_operation : Annotated[List[AccessMetadataOperation], Field(description="The Json patch document")], effective_at : Annotated[Optional[StrictStr], Field( description="The date this rule will be effective from")] = None, effective_until : Annotated[Optional[datetime], Field(description="The effective date until which the Access Metadata is valid. If not supplied this will be valid indefinitely, or until the next 'effectiveAt' date of the Access Metadata")] = None, **kwargs) -> ApiResponse:  # noqa: E501
        """[EARLY ACCESS] PatchPortfolioGroupAccessMetadata: Patch Access Metadata rules for a Portfolio Group.  # noqa: E501

        Patch Portfolio Group Access Metadata Rules in a single scope.  The behaviour is defined by the JSON Patch specification.                Currently only 'add' is a supported operation on the patch document.    Currently only valid metadata keys are supported paths on the patch document.                The response will return any affected Portfolio Group Access Metadata rules or a failure message if unsuccessful.                It is important to always check to verify success (or failure).                Multiple rules for a metadataKey can exist with different effective at dates, when resources are accessed the rule that is active for the current time will be fetched.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.patch_portfolio_group_access_metadata_with_http_info(scope, code, access_metadata_operation, effective_at, effective_until, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the Portfolio Group (required)
        :type scope: str
        :param code: The Portfolio Group code (required)
        :type code: str
        :param access_metadata_operation: The Json patch document (required)
        :type access_metadata_operation: List[AccessMetadataOperation]
        :param effective_at: The date this rule will be effective from
        :type effective_at: str
        :param effective_until: The effective date until which the Access Metadata is valid. If not supplied this will be valid indefinitely, or until the next 'effectiveAt' date of the Access Metadata
        :type effective_until: datetime
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _preload_content: if False, the ApiResponse.data will
                                 be set to none and raw_data will store the
                                 HTTP response body without reading/decoding.
                                 Default is True.
        :type _preload_content: bool, optional
        :param _return_http_data_only: response data instead of ApiResponse
                                       object with status code, headers, etc
        :type _return_http_data_only: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the authentication
                              in the spec for a single request.
        :type _request_auth: dict, optional
        :type _content_type: string, optional: force content-type for the request
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: tuple(Dict[str, List[AccessMetadataValue]], status_code(int), headers(HTTPHeaderDict))
        """

        _params = locals()

        _all_params = [
            'scope',
            'code',
            'access_metadata_operation',
            'effective_at',
            'effective_until'
        ]
        _all_params.extend(
            [
                'async_req',
                '_return_http_data_only',
                '_preload_content',
                '_request_timeout',
                '_request_auth',
                '_content_type',
                '_headers',
                'opts'
            ]
        )

        # validate the arguments
        for _key, _val in _params['kwargs'].items():
            if _key not in _all_params:
                raise ApiTypeError(
                    "Got an unexpected keyword argument '%s'"
                    " to method patch_portfolio_group_access_metadata" % _key
                )
            _params[_key] = _val
        del _params['kwargs']

        _collection_formats = {}

        # process the path parameters
        _path_params = {}
        if _params['scope']:
            _path_params['scope'] = _params['scope']

        if _params['code']:
            _path_params['code'] = _params['code']


        # process the query parameters
        _query_params = []
        if _params.get('effective_at') is not None:  # noqa: E501
            _query_params.append(('effectiveAt', _params['effective_at']))

        if _params.get('effective_until') is not None:  # noqa: E501
            if isinstance(_params['effective_until'], datetime):
                _query_params.append(('effectiveUntil', _params['effective_until'].strftime(self.api_client.configuration.datetime_format)))
            else:
                _query_params.append(('effectiveUntil', _params['effective_until']))

        # process the header parameters
        _header_params = dict(_params.get('_headers', {}))
        # process the form parameters
        _form_params = []
        _files = {}
        # process the body parameter
        _body_params = None
        if _params['access_metadata_operation'] is not None:
            _body_params = _params['access_metadata_operation']

        # set the HTTP header `Accept`
        _header_params['Accept'] = self.api_client.select_header_accept(
            ['text/plain', 'application/json', 'text/json'])  # noqa: E501

        # set the HTTP header `Content-Type`
        _content_types_list = _params.get('_content_type',
            self.api_client.select_header_content_type(
                ['application/json-patch+json', 'application/json', 'text/json', 'application/*+json']))
        if _content_types_list:
                _header_params['Content-Type'] = _content_types_list

        # authentication setting
        _auth_settings = ['oauth2']  # noqa: E501

        _response_types_map = {
            '200': "Dict[str, List[AccessMetadataValue]]",
            '400': "LusidValidationProblemDetails",
        }

        return self.api_client.call_api(
            '/api/portfoliogroups/{scope}/{code}/metadata', 'PATCH',
            _path_params,
            _query_params,
            _header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            response_types_map=_response_types_map,
            auth_settings=_auth_settings,
            async_req=_params.get('async_req'),
            _return_http_data_only=_params.get('_return_http_data_only'),  # noqa: E501
            _preload_content=_params.get('_preload_content', True),
            _request_timeout=_params.get('_request_timeout'),
            opts=_params.get('opts'),
            collection_formats=_collection_formats,
            _request_auth=_params.get('_request_auth'))


    @overload
    async def update_portfolio_group(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group to update the definition for.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group to update the definition for. Together with the scope this uniquely identifies the portfolio group.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label at which to update the definition.")] = None, update_portfolio_group_request : Annotated[Optional[UpdatePortfolioGroupRequest], Field(description="The updated portfolio group definition.")] = None, **kwargs) -> PortfolioGroup:  # noqa: E501
        ...

    @overload
    def update_portfolio_group(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group to update the definition for.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group to update the definition for. Together with the scope this uniquely identifies the portfolio group.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label at which to update the definition.")] = None, update_portfolio_group_request : Annotated[Optional[UpdatePortfolioGroupRequest], Field(description="The updated portfolio group definition.")] = None, async_req: Optional[bool]=True, **kwargs) -> PortfolioGroup:  # noqa: E501
        ...

    @validate_arguments
    def update_portfolio_group(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group to update the definition for.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group to update the definition for. Together with the scope this uniquely identifies the portfolio group.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label at which to update the definition.")] = None, update_portfolio_group_request : Annotated[Optional[UpdatePortfolioGroupRequest], Field(description="The updated portfolio group definition.")] = None, async_req: Optional[bool]=None, **kwargs) -> Union[PortfolioGroup, Awaitable[PortfolioGroup]]:  # noqa: E501
        """[EARLY ACCESS] UpdatePortfolioGroup: Update portfolio group  # noqa: E501

        Update the definition of a single portfolio group. Not all elements within a portfolio group definition are modifiable  due to the potential implications for data already stored against the portfolio group.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.update_portfolio_group(scope, code, effective_at, update_portfolio_group_request, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the portfolio group to update the definition for. (required)
        :type scope: str
        :param code: The code of the portfolio group to update the definition for. Together with the scope this uniquely identifies the portfolio group. (required)
        :type code: str
        :param effective_at: The effective datetime or cut label at which to update the definition.
        :type effective_at: str
        :param update_portfolio_group_request: The updated portfolio group definition.
        :type update_portfolio_group_request: UpdatePortfolioGroupRequest
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: PortfolioGroup
        """
        kwargs['_return_http_data_only'] = True
        if '_preload_content' in kwargs:
            message = "Error! Please call the update_portfolio_group_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data"  # noqa: E501
            raise ValueError(message)
        if async_req is not None:
            kwargs['async_req'] = async_req
        return self.update_portfolio_group_with_http_info(scope, code, effective_at, update_portfolio_group_request, **kwargs)  # noqa: E501

    @validate_arguments
    def update_portfolio_group_with_http_info(self, scope : Annotated[StrictStr, Field(..., description="The scope of the portfolio group to update the definition for.")], code : Annotated[StrictStr, Field(..., description="The code of the portfolio group to update the definition for. Together with the scope this uniquely identifies the portfolio group.")], effective_at : Annotated[Optional[StrictStr], Field( description="The effective datetime or cut label at which to update the definition.")] = None, update_portfolio_group_request : Annotated[Optional[UpdatePortfolioGroupRequest], Field(description="The updated portfolio group definition.")] = None, **kwargs) -> ApiResponse:  # noqa: E501
        """[EARLY ACCESS] UpdatePortfolioGroup: Update portfolio group  # noqa: E501

        Update the definition of a single portfolio group. Not all elements within a portfolio group definition are modifiable  due to the potential implications for data already stored against the portfolio group.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.update_portfolio_group_with_http_info(scope, code, effective_at, update_portfolio_group_request, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the portfolio group to update the definition for. (required)
        :type scope: str
        :param code: The code of the portfolio group to update the definition for. Together with the scope this uniquely identifies the portfolio group. (required)
        :type code: str
        :param effective_at: The effective datetime or cut label at which to update the definition.
        :type effective_at: str
        :param update_portfolio_group_request: The updated portfolio group definition.
        :type update_portfolio_group_request: UpdatePortfolioGroupRequest
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _preload_content: if False, the ApiResponse.data will
                                 be set to none and raw_data will store the
                                 HTTP response body without reading/decoding.
                                 Default is True.
        :type _preload_content: bool, optional
        :param _return_http_data_only: response data instead of ApiResponse
                                       object with status code, headers, etc
        :type _return_http_data_only: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the authentication
                              in the spec for a single request.
        :type _request_auth: dict, optional
        :type _content_type: string, optional: force content-type for the request
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: tuple(PortfolioGroup, status_code(int), headers(HTTPHeaderDict))
        """

        _params = locals()

        _all_params = [
            'scope',
            'code',
            'effective_at',
            'update_portfolio_group_request'
        ]
        _all_params.extend(
            [
                'async_req',
                '_return_http_data_only',
                '_preload_content',
                '_request_timeout',
                '_request_auth',
                '_content_type',
                '_headers',
                'opts'
            ]
        )

        # validate the arguments
        for _key, _val in _params['kwargs'].items():
            if _key not in _all_params:
                raise ApiTypeError(
                    "Got an unexpected keyword argument '%s'"
                    " to method update_portfolio_group" % _key
                )
            _params[_key] = _val
        del _params['kwargs']

        _collection_formats = {}

        # process the path parameters
        _path_params = {}
        if _params['scope']:
            _path_params['scope'] = _params['scope']

        if _params['code']:
            _path_params['code'] = _params['code']


        # process the query parameters
        _query_params = []
        if _params.get('effective_at') is not None:  # noqa: E501
            _query_params.append(('effectiveAt', _params['effective_at']))

        # process the header parameters
        _header_params = dict(_params.get('_headers', {}))
        # process the form parameters
        _form_params = []
        _files = {}
        # process the body parameter
        _body_params = None
        if _params['update_portfolio_group_request'] is not None:
            _body_params = _params['update_portfolio_group_request']

        # set the HTTP header `Accept`
        _header_params['Accept'] = self.api_client.select_header_accept(
            ['text/plain', 'application/json', 'text/json'])  # noqa: E501

        # set the HTTP header `Content-Type`
        _content_types_list = _params.get('_content_type',
            self.api_client.select_header_content_type(
                ['application/json-patch+json', 'application/json', 'text/json', 'application/*+json']))
        if _content_types_list:
                _header_params['Content-Type'] = _content_types_list

        # authentication setting
        _auth_settings = ['oauth2']  # noqa: E501

        _response_types_map = {
            '200': "PortfolioGroup",
            '400': "LusidValidationProblemDetails",
        }

        return self.api_client.call_api(
            '/api/portfoliogroups/{scope}/{code}', 'PUT',
            _path_params,
            _query_params,
            _header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            response_types_map=_response_types_map,
            auth_settings=_auth_settings,
            async_req=_params.get('async_req'),
            _return_http_data_only=_params.get('_return_http_data_only'),  # noqa: E501
            _preload_content=_params.get('_preload_content', True),
            _request_timeout=_params.get('_request_timeout'),
            opts=_params.get('opts'),
            collection_formats=_collection_formats,
            _request_auth=_params.get('_request_auth'))


    @overload
    async def upsert_group_properties(self, scope : Annotated[StrictStr, Field(..., description="The scope of the group to update or insert the properties onto.")], code : Annotated[StrictStr, Field(..., description="The code of the group to update or insert the properties onto. Together with the scope this uniquely identifies the group.")], request_body : Annotated[Optional[Dict[str, ModelProperty]], Field(description="The properties to be updated or inserted onto the group. Each property in               the request must be keyed by its unique property key. This has the format {domain}/{scope}/{code} e.g. \"PortfolioGroup/Manager/Id\".")] = None, **kwargs) -> PortfolioGroupProperties:  # noqa: E501
        ...

    @overload
    def upsert_group_properties(self, scope : Annotated[StrictStr, Field(..., description="The scope of the group to update or insert the properties onto.")], code : Annotated[StrictStr, Field(..., description="The code of the group to update or insert the properties onto. Together with the scope this uniquely identifies the group.")], request_body : Annotated[Optional[Dict[str, ModelProperty]], Field(description="The properties to be updated or inserted onto the group. Each property in               the request must be keyed by its unique property key. This has the format {domain}/{scope}/{code} e.g. \"PortfolioGroup/Manager/Id\".")] = None, async_req: Optional[bool]=True, **kwargs) -> PortfolioGroupProperties:  # noqa: E501
        ...

    @validate_arguments
    def upsert_group_properties(self, scope : Annotated[StrictStr, Field(..., description="The scope of the group to update or insert the properties onto.")], code : Annotated[StrictStr, Field(..., description="The code of the group to update or insert the properties onto. Together with the scope this uniquely identifies the group.")], request_body : Annotated[Optional[Dict[str, ModelProperty]], Field(description="The properties to be updated or inserted onto the group. Each property in               the request must be keyed by its unique property key. This has the format {domain}/{scope}/{code} e.g. \"PortfolioGroup/Manager/Id\".")] = None, async_req: Optional[bool]=None, **kwargs) -> Union[PortfolioGroupProperties, Awaitable[PortfolioGroupProperties]]:  # noqa: E501
        """[EARLY ACCESS] UpsertGroupProperties: Upsert group properties  # noqa: E501

        Update or insert one or more properties onto a single group. A property will be updated if it  already exists and inserted if it does not. All properties must be of the domain 'PortfolioGroup'.                Upserting a property that exists for a group, with a null value, will delete the instance of the property for that group.                Properties have an <i>effectiveFrom</i> datetime for which the property is valid, and an <i>effectiveUntil</i>  datetime until which the property is valid. Not supplying an <i>effectiveUntil</i> datetime results in the property being  valid indefinitely, or until the next <i>effectiveFrom</i> datetime of the property.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.upsert_group_properties(scope, code, request_body, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the group to update or insert the properties onto. (required)
        :type scope: str
        :param code: The code of the group to update or insert the properties onto. Together with the scope this uniquely identifies the group. (required)
        :type code: str
        :param request_body: The properties to be updated or inserted onto the group. Each property in               the request must be keyed by its unique property key. This has the format {domain}/{scope}/{code} e.g. \"PortfolioGroup/Manager/Id\".
        :type request_body: Dict[str, ModelProperty]
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: PortfolioGroupProperties
        """
        kwargs['_return_http_data_only'] = True
        if '_preload_content' in kwargs:
            message = "Error! Please call the upsert_group_properties_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data"  # noqa: E501
            raise ValueError(message)
        if async_req is not None:
            kwargs['async_req'] = async_req
        return self.upsert_group_properties_with_http_info(scope, code, request_body, **kwargs)  # noqa: E501

    @validate_arguments
    def upsert_group_properties_with_http_info(self, scope : Annotated[StrictStr, Field(..., description="The scope of the group to update or insert the properties onto.")], code : Annotated[StrictStr, Field(..., description="The code of the group to update or insert the properties onto. Together with the scope this uniquely identifies the group.")], request_body : Annotated[Optional[Dict[str, ModelProperty]], Field(description="The properties to be updated or inserted onto the group. Each property in               the request must be keyed by its unique property key. This has the format {domain}/{scope}/{code} e.g. \"PortfolioGroup/Manager/Id\".")] = None, **kwargs) -> ApiResponse:  # noqa: E501
        """[EARLY ACCESS] UpsertGroupProperties: Upsert group properties  # noqa: E501

        Update or insert one or more properties onto a single group. A property will be updated if it  already exists and inserted if it does not. All properties must be of the domain 'PortfolioGroup'.                Upserting a property that exists for a group, with a null value, will delete the instance of the property for that group.                Properties have an <i>effectiveFrom</i> datetime for which the property is valid, and an <i>effectiveUntil</i>  datetime until which the property is valid. Not supplying an <i>effectiveUntil</i> datetime results in the property being  valid indefinitely, or until the next <i>effectiveFrom</i> datetime of the property.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.upsert_group_properties_with_http_info(scope, code, request_body, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the group to update or insert the properties onto. (required)
        :type scope: str
        :param code: The code of the group to update or insert the properties onto. Together with the scope this uniquely identifies the group. (required)
        :type code: str
        :param request_body: The properties to be updated or inserted onto the group. Each property in               the request must be keyed by its unique property key. This has the format {domain}/{scope}/{code} e.g. \"PortfolioGroup/Manager/Id\".
        :type request_body: Dict[str, ModelProperty]
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _preload_content: if False, the ApiResponse.data will
                                 be set to none and raw_data will store the
                                 HTTP response body without reading/decoding.
                                 Default is True.
        :type _preload_content: bool, optional
        :param _return_http_data_only: response data instead of ApiResponse
                                       object with status code, headers, etc
        :type _return_http_data_only: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the authentication
                              in the spec for a single request.
        :type _request_auth: dict, optional
        :type _content_type: string, optional: force content-type for the request
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: tuple(PortfolioGroupProperties, status_code(int), headers(HTTPHeaderDict))
        """

        _params = locals()

        _all_params = [
            'scope',
            'code',
            'request_body'
        ]
        _all_params.extend(
            [
                'async_req',
                '_return_http_data_only',
                '_preload_content',
                '_request_timeout',
                '_request_auth',
                '_content_type',
                '_headers',
                'opts'
            ]
        )

        # validate the arguments
        for _key, _val in _params['kwargs'].items():
            if _key not in _all_params:
                raise ApiTypeError(
                    "Got an unexpected keyword argument '%s'"
                    " to method upsert_group_properties" % _key
                )
            _params[_key] = _val
        del _params['kwargs']

        _collection_formats = {}

        # process the path parameters
        _path_params = {}
        if _params['scope']:
            _path_params['scope'] = _params['scope']

        if _params['code']:
            _path_params['code'] = _params['code']


        # process the query parameters
        _query_params = []
        # process the header parameters
        _header_params = dict(_params.get('_headers', {}))
        # process the form parameters
        _form_params = []
        _files = {}
        # process the body parameter
        _body_params = None
        if _params['request_body'] is not None:
            _body_params = _params['request_body']

        # set the HTTP header `Accept`
        _header_params['Accept'] = self.api_client.select_header_accept(
            ['text/plain', 'application/json', 'text/json'])  # noqa: E501

        # set the HTTP header `Content-Type`
        _content_types_list = _params.get('_content_type',
            self.api_client.select_header_content_type(
                ['application/json-patch+json', 'application/json', 'text/json', 'application/*+json']))
        if _content_types_list:
                _header_params['Content-Type'] = _content_types_list

        # authentication setting
        _auth_settings = ['oauth2']  # noqa: E501

        _response_types_map = {
            '200': "PortfolioGroupProperties",
            '400': "LusidValidationProblemDetails",
        }

        return self.api_client.call_api(
            '/api/portfoliogroups/{scope}/{code}/properties/$upsert', 'POST',
            _path_params,
            _query_params,
            _header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            response_types_map=_response_types_map,
            auth_settings=_auth_settings,
            async_req=_params.get('async_req'),
            _return_http_data_only=_params.get('_return_http_data_only'),  # noqa: E501
            _preload_content=_params.get('_preload_content', True),
            _request_timeout=_params.get('_request_timeout'),
            opts=_params.get('opts'),
            collection_formats=_collection_formats,
            _request_auth=_params.get('_request_auth'))


    @overload
    async def upsert_portfolio_group_access_metadata(self, scope : Annotated[StrictStr, Field(..., description="The scope of the Portfolio Group")], code : Annotated[StrictStr, Field(..., description="The Portfolio Group code")], metadata_key : Annotated[StrictStr, Field(..., description="Key of the access metadata entry to upsert")], upsert_portfolio_group_access_metadata_request : Annotated[UpsertPortfolioGroupAccessMetadataRequest, Field(description="The Portfolio Group Access Metadata rule to upsert")], effective_at : Annotated[Optional[StrictStr], Field( description="The date this rule will be effective from")] = None, effective_until : Annotated[Optional[datetime], Field(description="The effective date until which the Access Metadata is valid. If not supplied this will be valid indefinitely, or until the next 'effectiveAt' date of the Access Metadata")] = None, **kwargs) -> ResourceListOfAccessMetadataValueOf:  # noqa: E501
        ...

    @overload
    def upsert_portfolio_group_access_metadata(self, scope : Annotated[StrictStr, Field(..., description="The scope of the Portfolio Group")], code : Annotated[StrictStr, Field(..., description="The Portfolio Group code")], metadata_key : Annotated[StrictStr, Field(..., description="Key of the access metadata entry to upsert")], upsert_portfolio_group_access_metadata_request : Annotated[UpsertPortfolioGroupAccessMetadataRequest, Field(description="The Portfolio Group Access Metadata rule to upsert")], effective_at : Annotated[Optional[StrictStr], Field( description="The date this rule will be effective from")] = None, effective_until : Annotated[Optional[datetime], Field(description="The effective date until which the Access Metadata is valid. If not supplied this will be valid indefinitely, or until the next 'effectiveAt' date of the Access Metadata")] = None, async_req: Optional[bool]=True, **kwargs) -> ResourceListOfAccessMetadataValueOf:  # noqa: E501
        ...

    @validate_arguments
    def upsert_portfolio_group_access_metadata(self, scope : Annotated[StrictStr, Field(..., description="The scope of the Portfolio Group")], code : Annotated[StrictStr, Field(..., description="The Portfolio Group code")], metadata_key : Annotated[StrictStr, Field(..., description="Key of the access metadata entry to upsert")], upsert_portfolio_group_access_metadata_request : Annotated[UpsertPortfolioGroupAccessMetadataRequest, Field(description="The Portfolio Group Access Metadata rule to upsert")], effective_at : Annotated[Optional[StrictStr], Field( description="The date this rule will be effective from")] = None, effective_until : Annotated[Optional[datetime], Field(description="The effective date until which the Access Metadata is valid. If not supplied this will be valid indefinitely, or until the next 'effectiveAt' date of the Access Metadata")] = None, async_req: Optional[bool]=None, **kwargs) -> Union[ResourceListOfAccessMetadataValueOf, Awaitable[ResourceListOfAccessMetadataValueOf]]:  # noqa: E501
        """UpsertPortfolioGroupAccessMetadata: Upsert a Portfolio Group Access Metadata entry associated with a specific metadataKey. This creates or updates the data in LUSID.  # noqa: E501

        Update or insert one Portfolio Group Access Metadata Entry in a single scope. An item will be updated if it already exists  and inserted if it does not.                The response will return the successfully updated or inserted Portfolio Group Access Metadata rule or failure message if unsuccessful.                It is important to always check to verify success (or failure).                Multiple rules for a metadataKey can exist with different effective at dates, when resources are accessed the rule that is active for the current time will be fetched.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.upsert_portfolio_group_access_metadata(scope, code, metadata_key, upsert_portfolio_group_access_metadata_request, effective_at, effective_until, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the Portfolio Group (required)
        :type scope: str
        :param code: The Portfolio Group code (required)
        :type code: str
        :param metadata_key: Key of the access metadata entry to upsert (required)
        :type metadata_key: str
        :param upsert_portfolio_group_access_metadata_request: The Portfolio Group Access Metadata rule to upsert (required)
        :type upsert_portfolio_group_access_metadata_request: UpsertPortfolioGroupAccessMetadataRequest
        :param effective_at: The date this rule will be effective from
        :type effective_at: str
        :param effective_until: The effective date until which the Access Metadata is valid. If not supplied this will be valid indefinitely, or until the next 'effectiveAt' date of the Access Metadata
        :type effective_until: datetime
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: ResourceListOfAccessMetadataValueOf
        """
        kwargs['_return_http_data_only'] = True
        if '_preload_content' in kwargs:
            message = "Error! Please call the upsert_portfolio_group_access_metadata_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data"  # noqa: E501
            raise ValueError(message)
        if async_req is not None:
            kwargs['async_req'] = async_req
        return self.upsert_portfolio_group_access_metadata_with_http_info(scope, code, metadata_key, upsert_portfolio_group_access_metadata_request, effective_at, effective_until, **kwargs)  # noqa: E501

    @validate_arguments
    def upsert_portfolio_group_access_metadata_with_http_info(self, scope : Annotated[StrictStr, Field(..., description="The scope of the Portfolio Group")], code : Annotated[StrictStr, Field(..., description="The Portfolio Group code")], metadata_key : Annotated[StrictStr, Field(..., description="Key of the access metadata entry to upsert")], upsert_portfolio_group_access_metadata_request : Annotated[UpsertPortfolioGroupAccessMetadataRequest, Field(description="The Portfolio Group Access Metadata rule to upsert")], effective_at : Annotated[Optional[StrictStr], Field( description="The date this rule will be effective from")] = None, effective_until : Annotated[Optional[datetime], Field(description="The effective date until which the Access Metadata is valid. If not supplied this will be valid indefinitely, or until the next 'effectiveAt' date of the Access Metadata")] = None, **kwargs) -> ApiResponse:  # noqa: E501
        """UpsertPortfolioGroupAccessMetadata: Upsert a Portfolio Group Access Metadata entry associated with a specific metadataKey. This creates or updates the data in LUSID.  # noqa: E501

        Update or insert one Portfolio Group Access Metadata Entry in a single scope. An item will be updated if it already exists  and inserted if it does not.                The response will return the successfully updated or inserted Portfolio Group Access Metadata rule or failure message if unsuccessful.                It is important to always check to verify success (or failure).                Multiple rules for a metadataKey can exist with different effective at dates, when resources are accessed the rule that is active for the current time will be fetched.  # noqa: E501
        This method makes a synchronous HTTP request by default. To make an
        asynchronous HTTP request, please pass async_req=True

        >>> thread = api.upsert_portfolio_group_access_metadata_with_http_info(scope, code, metadata_key, upsert_portfolio_group_access_metadata_request, effective_at, effective_until, async_req=True)
        >>> result = thread.get()

        :param scope: The scope of the Portfolio Group (required)
        :type scope: str
        :param code: The Portfolio Group code (required)
        :type code: str
        :param metadata_key: Key of the access metadata entry to upsert (required)
        :type metadata_key: str
        :param upsert_portfolio_group_access_metadata_request: The Portfolio Group Access Metadata rule to upsert (required)
        :type upsert_portfolio_group_access_metadata_request: UpsertPortfolioGroupAccessMetadataRequest
        :param effective_at: The date this rule will be effective from
        :type effective_at: str
        :param effective_until: The effective date until which the Access Metadata is valid. If not supplied this will be valid indefinitely, or until the next 'effectiveAt' date of the Access Metadata
        :type effective_until: datetime
        :param async_req: Whether to execute the request asynchronously.
        :type async_req: bool, optional
        :param _preload_content: if False, the ApiResponse.data will
                                 be set to none and raw_data will store the
                                 HTTP response body without reading/decoding.
                                 Default is True.
        :type _preload_content: bool, optional
        :param _return_http_data_only: response data instead of ApiResponse
                                       object with status code, headers, etc
        :type _return_http_data_only: bool, optional
        :param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
        :param opts: Configuration options for this request
        :type opts: ConfigurationOptions, optional
        :param _request_auth: set to override the auth_settings for an a single
                              request; this effectively ignores the authentication
                              in the spec for a single request.
        :type _request_auth: dict, optional
        :type _content_type: string, optional: force content-type for the request
        :return: Returns the result object.
                 If the method is called asynchronously,
                 returns the request thread.
        :rtype: tuple(ResourceListOfAccessMetadataValueOf, status_code(int), headers(HTTPHeaderDict))
        """

        _params = locals()

        _all_params = [
            'scope',
            'code',
            'metadata_key',
            'upsert_portfolio_group_access_metadata_request',
            'effective_at',
            'effective_until'
        ]
        _all_params.extend(
            [
                'async_req',
                '_return_http_data_only',
                '_preload_content',
                '_request_timeout',
                '_request_auth',
                '_content_type',
                '_headers',
                'opts'
            ]
        )

        # validate the arguments
        for _key, _val in _params['kwargs'].items():
            if _key not in _all_params:
                raise ApiTypeError(
                    "Got an unexpected keyword argument '%s'"
                    " to method upsert_portfolio_group_access_metadata" % _key
                )
            _params[_key] = _val
        del _params['kwargs']

        _collection_formats = {}

        # process the path parameters
        _path_params = {}
        if _params['scope']:
            _path_params['scope'] = _params['scope']

        if _params['code']:
            _path_params['code'] = _params['code']

        if _params['metadata_key']:
            _path_params['metadataKey'] = _params['metadata_key']


        # process the query parameters
        _query_params = []
        if _params.get('effective_at') is not None:  # noqa: E501
            _query_params.append(('effectiveAt', _params['effective_at']))

        if _params.get('effective_until') is not None:  # noqa: E501
            if isinstance(_params['effective_until'], datetime):
                _query_params.append(('effectiveUntil', _params['effective_until'].strftime(self.api_client.configuration.datetime_format)))
            else:
                _query_params.append(('effectiveUntil', _params['effective_until']))

        # process the header parameters
        _header_params = dict(_params.get('_headers', {}))
        # process the form parameters
        _form_params = []
        _files = {}
        # process the body parameter
        _body_params = None
        if _params['upsert_portfolio_group_access_metadata_request'] is not None:
            _body_params = _params['upsert_portfolio_group_access_metadata_request']

        # set the HTTP header `Accept`
        _header_params['Accept'] = self.api_client.select_header_accept(
            ['text/plain', 'application/json', 'text/json'])  # noqa: E501

        # set the HTTP header `Content-Type`
        _content_types_list = _params.get('_content_type',
            self.api_client.select_header_content_type(
                ['application/json-patch+json', 'application/json', 'text/json', 'application/*+json']))
        if _content_types_list:
                _header_params['Content-Type'] = _content_types_list

        # authentication setting
        _auth_settings = ['oauth2']  # noqa: E501

        _response_types_map = {
            '200': "ResourceListOfAccessMetadataValueOf",
            '400': "LusidValidationProblemDetails",
        }

        return self.api_client.call_api(
            '/api/portfoliogroups/{scope}/{code}/metadata/{metadataKey}', 'PUT',
            _path_params,
            _query_params,
            _header_params,
            body=_body_params,
            post_params=_form_params,
            files=_files,
            response_types_map=_response_types_map,
            auth_settings=_auth_settings,
            async_req=_params.get('async_req'),
            _return_http_data_only=_params.get('_return_http_data_only'),  # noqa: E501
            _preload_content=_params.get('_preload_content', True),
            _request_timeout=_params.get('_request_timeout'),
            opts=_params.get('opts'),
            collection_formats=_collection_formats,
            _request_auth=_params.get('_request_auth'))
