docs: def window(self, time_interval=None, force_calculation=False):
          """
          Gets a view on this stream for the time interval given
  
          :param time_interval: either a TimeInterval object or (start, end) tuple of type str or datetime
          :param force_calculation: Whether we should force calculation for this stream view if data does not exist
          :type time_interval: None | Iterable | TimeInterval
          :type force_calculation: bool
          :return: a stream view object
          """
          if not time_interval:
              if self.calculated_intervals:
                  time_interval = self.calculated_intervals[-1]
              else:
                  raise ValueError("No calculations have been performed and no time interval was provided")
          elif isinstance(time_interval, TimeInterval):
              time_interval = TimeInterval(time_interval.start, time_interval.end)
          elif isinstance(time_interval, Iterable):
              time_interval = parse_time_tuple(*time_interval)
              if isinstance(time_interval, RelativeTimeInterval):
                  raise NotImplementedError
          elif isinstance(time_interval, RelativeTimeInterval):
              raise NotImplementedError
          else:
              raise TypeError("Expected TimeInterval or (start, end) tuple of type str or datetime, got {}"
                              .format(type(time_interval)))
          return StreamView(stream=self, time_interval=time_interval, force_calculation=force_calculation)