def test_get_props(self):

        result = get_props.main(
            parse=lambda: get_props.parse(
                args=["--secrets", f"{self.secrets_file}"]),
            display_df=self.display_df,
        )
        self.validate_results_df(result)
def process_args(api, args):
    MAX_PROPS = 50

    def success(result):
        idents = [f"identifiers.KEY:{v}" for v in args.identifiers]
        columns = ["lusid_instrument_id", "name"]
        columns.extend(idents)
        if args.properties:
            columns.extend(["P:" + v for v in args.properties])

        df = lpt.to_df(result.content.values.values(), columns)
        return df.rename(columns=dict(zip(idents, args.identifiers)))

    if args.from_file:
        df = pd.read_csv(
            args.from_file[0])[args.from_file[1:]].drop_duplicates()
        args.instrument.extend(df[args.from_file[1]].values)

    def step3(result, props_remaining, final_dataframe):
        df = success(result)

        if final_dataframe is None:
            final_dataframe = df
        else:
            props = [c for c in df.columns.values if c.startswith("P:")]
            final_dataframe = final_dataframe.merge(
                df[["lusid_instrument_id"] + props],
                how="left",
                on="lusid_instrument_id",
            )

        if len(props_remaining) > 0:
            args.properties = props_remaining[:MAX_PROPS]
            remaining = props_remaining[MAX_PROPS:]
            return api.call.get_instruments(
                args.type,
                args.instrument,
                instrument_property_keys=args.properties).bind(
                    lambda r: step3(r, remaining, final_dataframe))
        return final_dataframe

    def step2(result=None):
        next_step = success
        if result is not None:
            # Contains full set of instrument properties
            l = list(
                result.apply(lambda r: f"Instrument/{r['scope']}/{r['code']}",
                             axis=1))
            args.properties = l[:MAX_PROPS]  # limitation
            if len(l) > MAX_PROPS:
                next_step = lambda r: step3(r, l[MAX_PROPS:], None)

        return api.call.get_instruments(
            args.type,
            args.instrument,
            instrument_property_keys=args.properties).bind(next_step)

    if args.identifiers is None:
        args.identifiers = [args.type]

    if args.properties:
        if args.properties[0] == "all":
            from lusidtools.lpt import qry_properties as qp

            return qp.process_args(
                api, qp.parse(args=["-d", "Instrument"])).bind(step2)

    return step2()