1from typing import Dict, NamedTuple, Optional, Union
2
3
4class Timestamp:
5 """A nanosecond-resolution timestamp."""
6
7 def __init__(self, sec: float, nsec: float) -> None:
8 if nsec < 0 or nsec >= 1e9:
9 raise ValueError(f"Invalid value for nanoseconds in Timestamp: {nsec}")
10 if sec < 0:
11 nsec = -nsec
12 self.sec: int = int(sec)
13 self.nsec: int = int(nsec)
14
15 def __str__(self) -> str:
16 return f"{self.sec}.{self.nsec:09d}"
17
18 def __repr__(self) -> str:
19 return f"Timestamp({self.sec}, {self.nsec})"
20
21 def __float__(self) -> float:
22 return float(self.sec) + float(self.nsec) / 1e9
23
24 def __eq__(self, other: object) -> bool:
25 return isinstance(other, Timestamp) and self.sec == other.sec and self.nsec == other.nsec
26
27 def __ne__(self, other: object) -> bool:
28 return not self == other
29
30 def __gt__(self, other: "Timestamp") -> bool:
31 return self.sec > other.sec or self.nsec > other.nsec
32
33 def __lt__(self, other: "Timestamp") -> bool:
34 return self.sec < other.sec or self.nsec < other.nsec
35
36
37# Timestamp and exemplar are optional.
38# Value can be an int or a float.
39# Timestamp can be a float containing a unixtime in seconds,
40# a Timestamp object, or None.
41# Exemplar can be an Exemplar object, or None.
42class Exemplar(NamedTuple):
43 labels: Dict[str, str]
44 value: float
45 timestamp: Optional[Union[float, Timestamp]] = None
46
47
48class Sample(NamedTuple):
49 name: str
50 labels: Dict[str, str]
51 value: float
52 timestamp: Optional[Union[float, Timestamp]] = None
53 exemplar: Optional[Exemplar] = None