# Path: hypebot/core/params_lib.py
# def _ParseChannel(channel):
# def _ParseChannels(channels):
#   def __init__(self, defaults=None):
#   def __str__(self):
#   def Override(self, params):
#   def _AssignValueConvertDict(self, key, value):
#   def _ParseDict(self, params):
#   def __setattr__(self, key, value):
#   def get(self, key, default_value=None):  # pylint: disable=invalid-name
#   def AsDict(self):
#   def Lock(self):
#   def _RaiseIfLocked(self):
# def MergeParams(defaults, *overrides):
# class HypeParams(object):
#   SPECIAL_ATTRS = ['_locked']
#   HAS_DYNAMIC_ATTRIBUTES = True
# 
# Path: hypebot/core/schedule_lib.py
# class HypeScheduler(object):
#   def __init__(self, local_tz: str = None):
#   def StartScheduler(self):
#   def InSeconds(self, seconds: int, fn: Callable, *args, **kwargs) -> Job:
#   def DailyCallback(self,
#                     schedule_time: arrow.Arrow,
#                     fn: Callable, *args, **kwargs) -> Job:
#   def FixedRate(self,
#                 initial_delay: int,
#                 period: int,
#                 fn: Callable, *args, **kwargs) -> Job:
#   def UnscheduleJob(self, job: Job) -> None:
# 
# Path: hypebot/hype_types.py



import abc
import json
import threading
import retrying
from typing import Any, AnyStr, Callable, List, Optional, Text, Tuple, Union
from absl import logging
from hypebot.core import params_lib
from hypebot.core import schedule_lib
from hypebot.hype_types import JsonType
  @abc.abstractmethod
  def GetHistoricalValues(
      self,
      key: AnyStr,
      subkey: AnyStr,
      num_past_values: int,
      tx: Optional[HypeTransaction] = None) -> List[JsonType]:
    """Like GetJsonValue, but allows for getting past values for key/subkey.

    Args:
      key: The primary key used to find the entry.
      subkey: The subkey used to find the entry.
      num_past_values: The maximum number of historical values to return. If
        fewer values are found (including 0 values), only that many values will
        be returned.
      tx: Optional transaction to run the underlying storage call within.

    Raises:
      If an error occurs during fetching the values from the store. This will
      abort any transaction GetHistoricalValues is called with.

    Returns:
      A list of the values found in reverse chronological order (newest values
      first). When no values are found, returns an empty list.
    """

  @abc.abstractmethod
  def PrependValue(self,
                   key: AnyStr,
                   subkey: AnyStr,

# Path: hypebot/core/params_lib.py
# def _ParseChannel(channel):
# def _ParseChannels(channels):
#   def __init__(self, defaults=None):
#   def __str__(self):
#   def Override(self, params):
#   def _AssignValueConvertDict(self, key, value):
#   def _ParseDict(self, params):
#   def __setattr__(self, key, value):
#   def get(self, key, default_value=None):  # pylint: disable=invalid-name
#   def AsDict(self):
#   def Lock(self):
#   def _RaiseIfLocked(self):
# def MergeParams(defaults, *overrides):
# class HypeParams(object):
#   SPECIAL_ATTRS = ['_locked']
#   HAS_DYNAMIC_ATTRIBUTES = True
# 
# Path: hypebot/core/schedule_lib.py
# class HypeScheduler(object):
#   def __init__(self, local_tz: str = None):
#   def StartScheduler(self):
#   def InSeconds(self, seconds: int, fn: Callable, *args, **kwargs) -> Job:
#   def DailyCallback(self,
#                     schedule_time: arrow.Arrow,
#                     fn: Callable, *args, **kwargs) -> Job:
#   def FixedRate(self,
#                 initial_delay: int,
#                 period: int,
#                 fn: Callable, *args, **kwargs) -> Job:
#   def UnscheduleJob(self, job: Job) -> None:
# 
# Path: hypebot/hype_types.py



# Path: hypebot/storage/storage_lib.py
import abc
import json
import threading
import retrying
from typing import Any, AnyStr, Callable, List, Optional, Text, Tuple, Union
from absl import logging
from hypebot.core import params_lib
from hypebot.core import schedule_lib
from hypebot.hype_types import JsonType

  @abc.abstractmethod
  def GetHistoricalValues(
      self,
      key: AnyStr,
      subkey: AnyStr,
      num_past_values: int,
      tx: Optional[HypeTransaction] = None) -> List[JsonType]:
    """Like GetJsonValue, but allows for getting past values for key/subkey.

    Args:
      key: The primary key used to find the entry.
      subkey: The subkey used to find the entry.
      num_past_values: The maximum number of historical values to return. If
        fewer values are found (including 0 values), only that many values will
        be returned.
      tx: Optional transaction to run the underlying storage call within.

    Raises:
      If an error occurs during fetching the values from the store. This will
      abort any transaction GetHistoricalValues is called with.

    Returns:
      A list of the values found in reverse chronological order (newest values
      first). When no values are found, returns an empty list.
    """

  @abc.abstractmethod
  def PrependValue(self,
                   key: AnyStr,
                   subkey: AnyStr,

                   new_value: JsonType,