docs: def query_metric_stats(self, metric_type, metric_id=None, start=None, end=None, bucketDuration=None, **query_options):
          """
          Query for metric aggregates from the server. This is called buckets in the Hawkular-Metrics documentation.
  
          :param metric_type: MetricType to be matched (required)
          :param metric_id: Exact string matching metric id or None for tags matching only
          :param start: Milliseconds since epoch or datetime instance
          :param end: Milliseconds since epoch or datetime instance
          :param bucketDuration: The timedelta or duration of buckets. Can be a string presentation or timedelta object
          :param query_options: For possible query_options, see the Hawkular-Metrics documentation.
          """
          if start is not None:
              if type(start) is datetime:
                  query_options['start'] = datetime_to_time_millis(start)
              else:
                  query_options['start'] = start
  
          if end is not None:
              if type(end) is datetime:
                  query_options['end'] = datetime_to_time_millis(end)
              else:
                  query_options['end'] = end
  
          if bucketDuration is not None:
              if type(bucketDuration) is timedelta:
                  query_options['bucketDuration'] = timedelta_to_duration(bucketDuration)
              else:
                  query_options['bucketDuration'] = bucketDuration
  
          if metric_id is not None:
              url = self._get_metrics_stats_url(self._get_metrics_single_url(metric_type, metric_id))
          else:
              if len(query_options) < 0:
                  raise HawkularError('Tags are required when querying without metric_id')
              url = self._get_metrics_stats_url(self._get_url(metric_type))
  
          return self._get(url, **query_options)