Source code for masterpiece_influx.influx_measurement
from typing import Any, Optional
from influxdb_client_3 import Point
from masterpiece.timeseries import Measurement
from typing import Optional, Any, Union, Dict
from influxdb_client_3 import Point
[docs]
class InfluxMeasurement(Point, Measurement):
"""
Concrete implementation of the Measurement class for InfluxDB.
Supports both dictionary-based and fluent interface initialization.
"""
def __init__(
self,
measurement_name: str,
tags: Optional[dict[str, str]] = None,
fields: Optional[dict[str, Any]] = None,
timestamp: Optional[str] = None,
) -> None:
"""
Initialize an InfluxMeasurement object.
"""
super().__init__(measurement_name)
self.tags = tags or {}
self.fields = fields or {}
self.timestamp = timestamp
self.name = measurement_name
# Add tags and fields to the Point object
for tag, value in self.tags.items():
self.tag(tag, value)
for field, value in self.fields.items():
self.field(field, value)
if self.timestamp:
self.time(self.timestamp)
[docs]
def tag(self, tag: str, value: str) -> "InfluxMeasurement":
"""
Add a tag to the measurement and return self for method chaining.
"""
super().tag(tag, value) # Call the Point method
self.tags[tag] = value
return self
[docs]
def field(
self, field: str, value: Union[int, float, str, bool]
) -> "InfluxMeasurement":
"""
Add a field to the measurement and return self for method chaining.
"""
super().field(field, value) # Call the Point method
self.fields[field] = value
return self
[docs]
def time(self, timestamp: Union[str, int]) -> "InfluxMeasurement":
"""
Set the timestamp for the measurement and return self for method chaining.
"""
super().time(timestamp) # Call the Point method
self.timestamp = timestamp
return self
[docs]
def to_dict(self) -> Dict[str, Any]:
"""
Convert the InfluxMeasurement to a dictionary.
"""
return {
"measurement": self.name,
"tags": self.tags,
"fields": self.fields,
"timestamp": self.timestamp,
}
[docs]
def from_dict(self, data: Dict[str, Any]) -> "InfluxMeasurement":
"""
Populate the InfluxMeasurement from a dictionary.
"""
self.name = data["measurement"]
self.tags = data.get("tags", {})
self.fields = data.get("fields", {})
self.timestamp = data.get("timestamp")
for tag, value in self.tags.items():
self.tag(tag, value)
for field, value in self.fields.items():
self.field(field, value)
if self.timestamp:
self.time(self.timestamp)
return self
[docs]
def validate(self) -> bool:
"""
Validate the measurement data.
- Ensure it has at least one field (InfluxDB requires fields).
- Validate that tags and fields are dictionaries.
"""
if not self.fields:
raise ValueError("InfluxMeasurement must have at least one field.")
if not isinstance(self.tags, dict) or not isinstance(self.fields, dict):
raise TypeError("Tags and fields must be dictionaries.")
return True