docs: def preview_data(self, flow_id, key=None, count=True, total=True):
          '''
          Get keys or number of series for a prospective dataset query allowing for
          keys with multiple values per dimension.
          It downloads the complete list of series keys for a dataflow rather than using constraints and DSD. This feature is,
          however, not supported by all data providers.
          ECB and UNSD are known to work.
  
          Args:
  
          flow_id(str): dataflow id
  
          key(dict): optional key mapping dimension names to values or lists of values.
              Must have been validated before. It is not checked if key values
              are actually valid dimension names and values. Default: {}
  
          count(bool): if True (default), return the number of series
              of the dataset designated by flow_id and key. If False,
              the actual keys are returned as a pandas DataFrame or dict of dataframes, depending on
              the value of 'total'.
  
          total(bool): if True (default), return the aggregate number
              of series or a single dataframe (depending on the value of 'count'). If False,
              return a dict mapping keys to dataframes of series keys.
              E.g., if key={'COUNTRY':'IT+CA+AU'}, the dict will
              have 3 items describing the series keys for each country
              respectively. If 'count' is True, dict values will be int rather than
              PD.DataFrame.
          '''
          all_keys = self.series_keys(flow_id)
          # Handle the special case that no key is provided
          if not key:
              if count:
                  return all_keys.shape[0]
              else:
                  return all_keys
  
          # So there is a key specifying at least one dimension value.
          # Wrap single values in 1-elem list for uniform treatment
          key_l = {k: [v] if isinstance(v, str_type) else v
                   for k, v in key.items()}
          # order dim_names that are present in the key
          dim_names = [k for k in all_keys if k in key]
          # Drop columns that are not in the key
          key_df = all_keys.loc[:, dim_names]
          if total:
              # DataFrame with matching series keys
              bool_series = reduce(
                  and_, (key_df.isin(key_l)[col] for col in dim_names))
              if count:
                  return bool_series.value_counts()[True]
              else:
                  return all_keys[bool_series]
          else:
              # Dict of value combinations as dict keys
              key_product = product(*(key_l[k] for k in dim_names))
              # Replace key tuples by namedtuples
              PartialKey = namedtuple_factory('PartialKey', dim_names)
  
              matches = {PartialKey(k): reduce(and_, (key_df.isin({k1: [v1]
                                                                   for k1, v1 in zip(dim_names, k)})[col]
                                                      for col in dim_names))
                         for k in key_product}
  
              if not count:
                  # dict mapping each key to DataFrame with selected key-set
                  return {k: all_keys[v] for k, v in matches.items()}
              else:
                  # Number of series per key
                  return {k: v.value_counts()[True] for k, v in matches.items()}