# Module `redvox.cloud.station_stats`

This module provides access to the timing station statistics through the RedVox Cloud API.

Expand source code

    """
    This module provides access to the timing station statistics through the RedVox Cloud API.
    """

    from datetime import datetime, timedelta
    from dataclasses import dataclass
    from typing import Callable, List, Optional, TypeVar

    import requests
    from dataclasses_json import dataclass_json

    import redvox.common.file_statistics as file_stats
    from redvox.cloud.api import post_req
    from redvox.cloud.config import RedVoxConfig
    from redvox.cloud.routes import RoutesV1
    from redvox.common.date_time_utils import (
        datetime_from_epoch_microseconds_utc as us2dt,
        datetime_to_epoch_microseconds_utc as dt2us,
    )

    T = TypeVar("T")
    R = TypeVar("R")

    def _map_opt(opt: Optional[T], f: Callable[[T], R]) -> Optional[R]:
        """
        Maps an optional with the given function.
        :param opt: The optional top map.
        :param f: The mapping function.
        :return: The mapped value or None.
        """
        if opt is not None:
            return f(opt)
        return None

    @dataclass_json
    @dataclass
    class GpsDateTime:
        """
        Represents timestamp pairings in API 1000 data.
        """

        mach_dt: float
        gps_dt: Optional[float]

        def into_file_stat(self) -> file_stats.GpsDateTime:
            """
            :return: Converts this into the file_statistics module representation.
            """
            gps_dt: Optional[datetime] = _map_opt(self.gps_dt, us2dt)
            return file_stats.GpsDateTime(us2dt(self.mach_dt), gps_dt)

    @dataclass_json
    @dataclass
    class StationStat:
        """
        A collection of station fields for a given API 900 or API 1000 packet.
        These are used for timing correction and gap detection.
        """

        station_id: str
        station_uuid: str
        app_start_dt: Optional[float]
        packet_start_dt: float
        server_recv_dt: Optional[float]
        gps_dts: Optional[List[GpsDateTime]]
        latency: Optional[float]
        offset: Optional[float]
        sample_rate_hz: Optional[float]
        packet_duration: Optional[float]

        def into_file_stat(self) -> file_stats.StationStat:
            """
            :return: Converts this into the file_statistics module representation.
            """
            return file_stats.StationStat(
                self.station_id,
                self.station_uuid,
                _map_opt(self.app_start_dt, us2dt),
                us2dt(self.packet_start_dt),
                _map_opt(self.server_recv_dt, us2dt),
                _map_opt(
                    self.gps_dts, lambda dts: list(map(GpsDateTime.into_file_stat, dts))
                ),
                self.latency,
                (self.packet_start_dt + (self.packet_duration / 2.0)),
                self.offset,
                self.sample_rate_hz,
                _map_opt(self.packet_duration, lambda dur: timedelta(microseconds=dur)),
            )

    @dataclass_json
    @dataclass
    class StationStatReq:
        """
        A StationStatReq container.
        """

        auth_token: str
        start_ts_s: int
        end_ts_s: int
        station_ids: List[str]
        secret_token: Optional[str] = None

    @dataclass
    class StationStatsResp:
        """
        A response type converted into the file_statistics module representation.
        """

        station_stats: List[file_stats.StationStat]

    @dataclass_json
    @dataclass
    class StationStatResp:
        """
        A response contain StationStat instances.
        """

        station_stats: List[StationStat]

        def into_station_stats_resp(self) -> StationStatsResp:
            return StationStatsResp(
                list(map(StationStat.into_file_stat, self.station_stats))
            )

    def request_station_stats(
        redvox_config: RedVoxConfig,
        station_stat_req: StationStatReq,
        session: Optional[requests.Session] = None,
        timeout: Optional[float] = None,
    ) -> Optional[StationStatsResp]:
        """
        Requests timing statistics with the given parameters.
        :param redvox_config: The cloud configuration.
        :param station_stat_req: The request.
        :param session: The optional session.
        :param timeout: The optional timeout.
        :return: A StationStatsResp.
        """
        # noinspection Mypy
        handle_resp: Callable[
            [requests.Response], StationStatResp
        ] = lambda resp: StationStatResp.from_dict(resp.json()).into_station_stats_resp()
        return post_req(
            redvox_config,
            RoutesV1.STATION_STATS,
            station_stat_req,
            handle_resp,
            session,
            timeout,
        )

## Functions

`def request_station_stats(redvox_config: RedVoxConfig, station_stat_req: StationStatReq, session: Optional[requests.sessions.Session] = None, timeout: Optional[float] = None) ‑> Optional[StationStatsResp]`

  Requests timing statistics with the given parameters. :param redvox_config: The cloud configuration. :param station_stat_req: The request. :param session: The optional session. :param timeout: The optional timeout. :return: A StationStatsResp.

  Expand source code

      def request_station_stats(
          redvox_config: RedVoxConfig,
          station_stat_req: StationStatReq,
          session: Optional[requests.Session] = None,
          timeout: Optional[float] = None,
      ) -> Optional[StationStatsResp]:
          """
          Requests timing statistics with the given parameters.
          :param redvox_config: The cloud configuration.
          :param station_stat_req: The request.
          :param session: The optional session.
          :param timeout: The optional timeout.
          :return: A StationStatsResp.
          """
          # noinspection Mypy
          handle_resp: Callable[
              [requests.Response], StationStatResp
          ] = lambda resp: StationStatResp.from_dict(resp.json()).into_station_stats_resp()
          return post_req(
              redvox_config,
              RoutesV1.STATION_STATS,
              station_stat_req,
              handle_resp,
              session,
              timeout,
          )

## Classes

`class GpsDateTime (mach_dt: float, gps_dt: Optional[float])`

  Represents timestamp pairings in API 1000 data.

  Expand source code

      @dataclass_json
      @dataclass
      class GpsDateTime:
          """
          Represents timestamp pairings in API 1000 data.
          """

          mach_dt: float
          gps_dt: Optional[float]

          def into_file_stat(self) -> file_stats.GpsDateTime:
              """
              :return: Converts this into the file_statistics module representation.
              """
              gps_dt: Optional[datetime] = _map_opt(self.gps_dt, us2dt)
              return file_stats.GpsDateTime(us2dt(self.mach_dt), gps_dt)

  ### Class variables

  `var gps_dt : Optional[float]`
  `var mach_dt : float`

  ### Static methods

  `def from_dict(kvs: Union[dict, list, str, int, float, bool, ForwardRef(None)], *, infer_missing=False) ‑> ~A`
    Expand source code

        @classmethod
        def from_dict(cls: Type[A],
                      kvs: Json,
                      *,
                      infer_missing=False) -> A:
            return _decode_dataclass(cls, kvs, infer_missing)

  `def from_json(s: Union[str, bytes, bytearray], *, parse_float=None, parse_int=None, parse_constant=None, infer_missing=False, **kw) ‑> ~A`
    Expand source code

        @classmethod
        def from_json(cls: Type[A],
                      s: JsonData,
                      *,
                      parse_float=None,
                      parse_int=None,
                      parse_constant=None,
                      infer_missing=False,
                      **kw) -> A:
            kvs = json.loads(s,
                             parse_float=parse_float,
                             parse_int=parse_int,
                             parse_constant=parse_constant,
                             **kw)
            return cls.from_dict(kvs, infer_missing=infer_missing)

  `def schema(*, infer_missing: bool = False, only=None, exclude=(), many: bool = False, context=None, load_only=(), dump_only=(), partial: bool = False, unknown=None) ‑> dataclasses_json.mm.SchemaF[~A]`
    Expand source code

        @classmethod
        def schema(cls: Type[A],
                   *,
                   infer_missing: bool = False,
                   only=None,
                   exclude=(),
                   many: bool = False,
                   context=None,
                   load_only=(),
                   dump_only=(),
                   partial: bool = False,
                   unknown=None) -> SchemaType:
            Schema = build_schema(cls, DataClassJsonMixin, infer_missing, partial)

            if unknown is None:
                undefined_parameter_action = _undefined_parameter_action_safe(cls)
                if undefined_parameter_action is not None:
                    # We can just make use of the same-named mm keywords
                    unknown = undefined_parameter_action.name.lower()

            return Schema(only=only,
                          exclude=exclude,
                          many=many,
                          context=context,
                          load_only=load_only,
                          dump_only=dump_only,
                          partial=partial,
                          unknown=unknown)

  ### Methods

  `def into_file_stat(self) ‑> GpsDateTime`

    :return: Converts this into the file_statistics module representation.

    Expand source code

        def into_file_stat(self) -> file_stats.GpsDateTime:
            """
            :return: Converts this into the file_statistics module representation.
            """
            gps_dt: Optional[datetime] = _map_opt(self.gps_dt, us2dt)
            return file_stats.GpsDateTime(us2dt(self.mach_dt), gps_dt)

  `def to_dict(self, encode_json=False) ‑> Dict[str, Union[dict, list, str, int, float, bool, ForwardRef(None)]]`
    Expand source code

        def to_dict(self, encode_json=False) -> Dict[str, Json]:
            return _asdict(self, encode_json=encode_json)

  `def to_json(self, *, skipkeys: bool = False, ensure_ascii: bool = True, check_circular: bool = True, allow_nan: bool = True, indent: Union[int, str, ForwardRef(None)] = None, separators: Tuple[str, str] = None, default: Callable = None, sort_keys: bool = False, **kw) ‑> str`
    Expand source code

        def to_json(self,
                    *,
                    skipkeys: bool = False,
                    ensure_ascii: bool = True,
                    check_circular: bool = True,
                    allow_nan: bool = True,
                    indent: Optional[Union[int, str]] = None,
                    separators: Tuple[str, str] = None,
                    default: Callable = None,
                    sort_keys: bool = False,
                    **kw) -> str:
            return json.dumps(self.to_dict(encode_json=False),
                              cls=_ExtendedEncoder,
                              skipkeys=skipkeys,
                              ensure_ascii=ensure_ascii,
                              check_circular=check_circular,
                              allow_nan=allow_nan,
                              indent=indent,
                              separators=separators,
                              default=default,
                              sort_keys=sort_keys,
                              **kw)

`class StationStat (station_id: str, station_uuid: str, app_start_dt: Optional[float], packet_start_dt: float, server_recv_dt: Optional[float], gps_dts: Optional[List[GpsDateTime]], latency: Optional[float], offset: Optional[float], sample_rate_hz: Optional[float], packet_duration: Optional[float])`

  A collection of station fields for a given API 900 or API 1000 packet. These are used for timing correction and gap detection.

  Expand source code

      @dataclass_json
      @dataclass
      class StationStat:
          """
          A collection of station fields for a given API 900 or API 1000 packet.
          These are used for timing correction and gap detection.
          """

          station_id: str
          station_uuid: str
          app_start_dt: Optional[float]
          packet_start_dt: float
          server_recv_dt: Optional[float]
          gps_dts: Optional[List[GpsDateTime]]
          latency: Optional[float]
          offset: Optional[float]
          sample_rate_hz: Optional[float]
          packet_duration: Optional[float]

          def into_file_stat(self) -> file_stats.StationStat:
              """
              :return: Converts this into the file_statistics module representation.
              """
              return file_stats.StationStat(
                  self.station_id,
                  self.station_uuid,
                  _map_opt(self.app_start_dt, us2dt),
                  us2dt(self.packet_start_dt),
                  _map_opt(self.server_recv_dt, us2dt),
                  _map_opt(
                      self.gps_dts, lambda dts: list(map(GpsDateTime.into_file_stat, dts))
                  ),
                  self.latency,
                  (self.packet_start_dt + (self.packet_duration / 2.0)),
                  self.offset,
                  self.sample_rate_hz,
                  _map_opt(self.packet_duration, lambda dur: timedelta(microseconds=dur)),
              )

  ### Class variables

  `var app_start_dt : Optional[float]`
  `var gps_dts : Optional[List[GpsDateTime]]`
  `var latency : Optional[float]`
  `var offset : Optional[float]`
  `var packet_duration : Optional[float]`
  `var packet_start_dt : float`
  `var sample_rate_hz : Optional[float]`
  `var server_recv_dt : Optional[float]`
  `var station_id : str`
  `var station_uuid : str`

  ### Static methods

  `def from_dict(kvs: Union[dict, list, str, int, float, bool, ForwardRef(None)], *, infer_missing=False) ‑> ~A`
    Expand source code

        @classmethod
        def from_dict(cls: Type[A],
                      kvs: Json,
                      *,
                      infer_missing=False) -> A:
            return _decode_dataclass(cls, kvs, infer_missing)

  `def from_json(s: Union[str, bytes, bytearray], *, parse_float=None, parse_int=None, parse_constant=None, infer_missing=False, **kw) ‑> ~A`
    Expand source code

        @classmethod
        def from_json(cls: Type[A],
                      s: JsonData,
                      *,
                      parse_float=None,
                      parse_int=None,
                      parse_constant=None,
                      infer_missing=False,
                      **kw) -> A:
            kvs = json.loads(s,
                             parse_float=parse_float,
                             parse_int=parse_int,
                             parse_constant=parse_constant,
                             **kw)
            return cls.from_dict(kvs, infer_missing=infer_missing)

  `def schema(*, infer_missing: bool = False, only=None, exclude=(), many: bool = False, context=None, load_only=(), dump_only=(), partial: bool = False, unknown=None) ‑> dataclasses_json.mm.SchemaF[~A]`
    Expand source code

        @classmethod
        def schema(cls: Type[A],
                   *,
                   infer_missing: bool = False,
                   only=None,
                   exclude=(),
                   many: bool = False,
                   context=None,
                   load_only=(),
                   dump_only=(),
                   partial: bool = False,
                   unknown=None) -> SchemaType:
            Schema = build_schema(cls, DataClassJsonMixin, infer_missing, partial)

            if unknown is None:
                undefined_parameter_action = _undefined_parameter_action_safe(cls)
                if undefined_parameter_action is not None:
                    # We can just make use of the same-named mm keywords
                    unknown = undefined_parameter_action.name.lower()

            return Schema(only=only,
                          exclude=exclude,
                          many=many,
                          context=context,
                          load_only=load_only,
                          dump_only=dump_only,
                          partial=partial,
                          unknown=unknown)

  ### Methods

  `def into_file_stat(self) ‑> StationStat`

    :return: Converts this into the file_statistics module representation.

    Expand source code

        def into_file_stat(self) -> file_stats.StationStat:
            """
            :return: Converts this into the file_statistics module representation.
            """
            return file_stats.StationStat(
                self.station_id,
                self.station_uuid,
                _map_opt(self.app_start_dt, us2dt),
                us2dt(self.packet_start_dt),
                _map_opt(self.server_recv_dt, us2dt),
                _map_opt(
                    self.gps_dts, lambda dts: list(map(GpsDateTime.into_file_stat, dts))
                ),
                self.latency,
                (self.packet_start_dt + (self.packet_duration / 2.0)),
                self.offset,
                self.sample_rate_hz,
                _map_opt(self.packet_duration, lambda dur: timedelta(microseconds=dur)),
            )

  `def to_dict(self, encode_json=False) ‑> Dict[str, Union[dict, list, str, int, float, bool, ForwardRef(None)]]`
    Expand source code

        def to_dict(self, encode_json=False) -> Dict[str, Json]:
            return _asdict(self, encode_json=encode_json)

  `def to_json(self, *, skipkeys: bool = False, ensure_ascii: bool = True, check_circular: bool = True, allow_nan: bool = True, indent: Union[int, str, ForwardRef(None)] = None, separators: Tuple[str, str] = None, default: Callable = None, sort_keys: bool = False, **kw) ‑> str`
    Expand source code

        def to_json(self,
                    *,
                    skipkeys: bool = False,
                    ensure_ascii: bool = True,
                    check_circular: bool = True,
                    allow_nan: bool = True,
                    indent: Optional[Union[int, str]] = None,
                    separators: Tuple[str, str] = None,
                    default: Callable = None,
                    sort_keys: bool = False,
                    **kw) -> str:
            return json.dumps(self.to_dict(encode_json=False),
                              cls=_ExtendedEncoder,
                              skipkeys=skipkeys,
                              ensure_ascii=ensure_ascii,
                              check_circular=check_circular,
                              allow_nan=allow_nan,
                              indent=indent,
                              separators=separators,
                              default=default,
                              sort_keys=sort_keys,
                              **kw)

`class StationStatReq (auth_token: str, start_ts_s: int, end_ts_s: int, station_ids: List[str], secret_token: Optional[str] = None)`

  A StationStatReq container.

  Expand source code

      @dataclass_json
      @dataclass
      class StationStatReq:
          """
          A StationStatReq container.
          """

          auth_token: str
          start_ts_s: int
          end_ts_s: int
          station_ids: List[str]
          secret_token: Optional[str] = None

  ### Class variables

  `var auth_token : str`
  `var end_ts_s : int`
  `var secret_token : Optional[str]`
  `var start_ts_s : int`
  `var station_ids : List[str]`

  ### Static methods

  `def from_dict(kvs: Union[dict, list, str, int, float, bool, ForwardRef(None)], *, infer_missing=False) ‑> ~A`
    Expand source code

        @classmethod
        def from_dict(cls: Type[A],
                      kvs: Json,
                      *,
                      infer_missing=False) -> A:
            return _decode_dataclass(cls, kvs, infer_missing)

  `def from_json(s: Union[str, bytes, bytearray], *, parse_float=None, parse_int=None, parse_constant=None, infer_missing=False, **kw) ‑> ~A`
    Expand source code

        @classmethod
        def from_json(cls: Type[A],
                      s: JsonData,
                      *,
                      parse_float=None,
                      parse_int=None,
                      parse_constant=None,
                      infer_missing=False,
                      **kw) -> A:
            kvs = json.loads(s,
                             parse_float=parse_float,
                             parse_int=parse_int,
                             parse_constant=parse_constant,
                             **kw)
            return cls.from_dict(kvs, infer_missing=infer_missing)

  `def schema(*, infer_missing: bool = False, only=None, exclude=(), many: bool = False, context=None, load_only=(), dump_only=(), partial: bool = False, unknown=None) ‑> dataclasses_json.mm.SchemaF[~A]`
    Expand source code

        @classmethod
        def schema(cls: Type[A],
                   *,
                   infer_missing: bool = False,
                   only=None,
                   exclude=(),
                   many: bool = False,
                   context=None,
                   load_only=(),
                   dump_only=(),
                   partial: bool = False,
                   unknown=None) -> SchemaType:
            Schema = build_schema(cls, DataClassJsonMixin, infer_missing, partial)

            if unknown is None:
                undefined_parameter_action = _undefined_parameter_action_safe(cls)
                if undefined_parameter_action is not None:
                    # We can just make use of the same-named mm keywords
                    unknown = undefined_parameter_action.name.lower()

            return Schema(only=only,
                          exclude=exclude,
                          many=many,
                          context=context,
                          load_only=load_only,
                          dump_only=dump_only,
                          partial=partial,
                          unknown=unknown)

  ### Methods

  `def to_dict(self, encode_json=False) ‑> Dict[str, Union[dict, list, str, int, float, bool, ForwardRef(None)]]`
    Expand source code

        def to_dict(self, encode_json=False) -> Dict[str, Json]:
            return _asdict(self, encode_json=encode_json)

  `def to_json(self, *, skipkeys: bool = False, ensure_ascii: bool = True, check_circular: bool = True, allow_nan: bool = True, indent: Union[int, str, ForwardRef(None)] = None, separators: Tuple[str, str] = None, default: Callable = None, sort_keys: bool = False, **kw) ‑> str`
    Expand source code

        def to_json(self,
                    *,
                    skipkeys: bool = False,
                    ensure_ascii: bool = True,
                    check_circular: bool = True,
                    allow_nan: bool = True,
                    indent: Optional[Union[int, str]] = None,
                    separators: Tuple[str, str] = None,
                    default: Callable = None,
                    sort_keys: bool = False,
                    **kw) -> str:
            return json.dumps(self.to_dict(encode_json=False),
                              cls=_ExtendedEncoder,
                              skipkeys=skipkeys,
                              ensure_ascii=ensure_ascii,
                              check_circular=check_circular,
                              allow_nan=allow_nan,
                              indent=indent,
                              separators=separators,
                              default=default,
                              sort_keys=sort_keys,
                              **kw)

`class StationStatResp (station_stats: List[StationStat])`

  A response contain StationStat instances.

  Expand source code

      @dataclass_json
      @dataclass
      class StationStatResp:
          """
          A response contain StationStat instances.
          """

          station_stats: List[StationStat]

          def into_station_stats_resp(self) -> StationStatsResp:
              return StationStatsResp(
                  list(map(StationStat.into_file_stat, self.station_stats))
              )

  ### Class variables

  `var station_stats : List[StationStat]`

  ### Static methods

  `def from_dict(kvs: Union[dict, list, str, int, float, bool, ForwardRef(None)], *, infer_missing=False) ‑> ~A`
    Expand source code

        @classmethod
        def from_dict(cls: Type[A],
                      kvs: Json,
                      *,
                      infer_missing=False) -> A:
            return _decode_dataclass(cls, kvs, infer_missing)

  `def from_json(s: Union[str, bytes, bytearray], *, parse_float=None, parse_int=None, parse_constant=None, infer_missing=False, **kw) ‑> ~A`
    Expand source code

        @classmethod
        def from_json(cls: Type[A],
                      s: JsonData,
                      *,
                      parse_float=None,
                      parse_int=None,
                      parse_constant=None,
                      infer_missing=False,
                      **kw) -> A:
            kvs = json.loads(s,
                             parse_float=parse_float,
                             parse_int=parse_int,
                             parse_constant=parse_constant,
                             **kw)
            return cls.from_dict(kvs, infer_missing=infer_missing)

  `def schema(*, infer_missing: bool = False, only=None, exclude=(), many: bool = False, context=None, load_only=(), dump_only=(), partial: bool = False, unknown=None) ‑> dataclasses_json.mm.SchemaF[~A]`
    Expand source code

        @classmethod
        def schema(cls: Type[A],
                   *,
                   infer_missing: bool = False,
                   only=None,
                   exclude=(),
                   many: bool = False,
                   context=None,
                   load_only=(),
                   dump_only=(),
                   partial: bool = False,
                   unknown=None) -> SchemaType:
            Schema = build_schema(cls, DataClassJsonMixin, infer_missing, partial)

            if unknown is None:
                undefined_parameter_action = _undefined_parameter_action_safe(cls)
                if undefined_parameter_action is not None:
                    # We can just make use of the same-named mm keywords
                    unknown = undefined_parameter_action.name.lower()

            return Schema(only=only,
                          exclude=exclude,
                          many=many,
                          context=context,
                          load_only=load_only,
                          dump_only=dump_only,
                          partial=partial,
                          unknown=unknown)

  ### Methods

  `def into_station_stats_resp(self) ‑> StationStatsResp`
    Expand source code

        def into_station_stats_resp(self) -> StationStatsResp:
            return StationStatsResp(
                list(map(StationStat.into_file_stat, self.station_stats))
            )

  `def to_dict(self, encode_json=False) ‑> Dict[str, Union[dict, list, str, int, float, bool, ForwardRef(None)]]`
    Expand source code

        def to_dict(self, encode_json=False) -> Dict[str, Json]:
            return _asdict(self, encode_json=encode_json)

  `def to_json(self, *, skipkeys: bool = False, ensure_ascii: bool = True, check_circular: bool = True, allow_nan: bool = True, indent: Union[int, str, ForwardRef(None)] = None, separators: Tuple[str, str] = None, default: Callable = None, sort_keys: bool = False, **kw) ‑> str`
    Expand source code

        def to_json(self,
                    *,
                    skipkeys: bool = False,
                    ensure_ascii: bool = True,
                    check_circular: bool = True,
                    allow_nan: bool = True,
                    indent: Optional[Union[int, str]] = None,
                    separators: Tuple[str, str] = None,
                    default: Callable = None,
                    sort_keys: bool = False,
                    **kw) -> str:
            return json.dumps(self.to_dict(encode_json=False),
                              cls=_ExtendedEncoder,
                              skipkeys=skipkeys,
                              ensure_ascii=ensure_ascii,
                              check_circular=check_circular,
                              allow_nan=allow_nan,
                              indent=indent,
                              separators=separators,
                              default=default,
                              sort_keys=sort_keys,
                              **kw)

`class StationStatsResp (station_stats: List[StationStat])`

  A response type converted into the file_statistics module representation.

  Expand source code

      @dataclass
      class StationStatsResp:
          """
          A response type converted into the file_statistics module representation.
          """

          station_stats: List[file_stats.StationStat]

  ### Class variables

  `var station_stats : List[StationStat]`