Source code for duct.protocol.influxdb3

"""
.. module:: influxdb3
   :synopsis: InfluxDB 3 protocol module

.. moduleauthor:: Colin Alston <colin@tamvera.com>
"""

from duct import utils


def _escape_tag(value):
    """Escape a tag key or value for line protocol"""
    return str(value).replace(',', r'\,').replace('=', r'\=').replace(' ', r'\ ')


def _escape_measurement(value):
    """Escape a measurement name for line protocol"""
    return str(value).replace(',', r'\,').replace(' ', r'\ ')


def _format_field(value):
    """Format a field value for line protocol"""
    if isinstance(value, bool):
        return 't' if value else 'f'
    if isinstance(value, int):
        return f'{value}i'
    if isinstance(value, float):
        return repr(value)
    return f'"{str(value).replace(chr(34), chr(92) + chr(34))}"'


[docs] def to_line_protocol(measurement, tags, fields, timestamp_ns): """Encode a single point in InfluxDB line protocol. :param measurement: Measurement name :param tags: Dict of tag key/value pairs :param fields: Dict of field key/value pairs :param timestamp_ns: Timestamp in nanoseconds :returns: Line protocol string (no trailing newline) """ tag_set = ','.join( f'{_escape_tag(k)}={_escape_tag(v)}' for k, v in sorted(tags.items()) ) field_set = ','.join( f'{_escape_tag(k)}={_format_field(v)}' for k, v in fields.items() ) meas = _escape_measurement(measurement) if tag_set: return f'{meas},{tag_set} {field_set} {timestamp_ns}' return f'{meas} {field_set} {timestamp_ns}'
[docs] class InfluxDB3Client: """InfluxDB 3 HTTP write client""" def __init__(self, url='http://localhost:8086', database='duct', token=None, precision='nanosecond'): self.url = url.rstrip('/') self.database = database self.token = token self.precision = precision def _headers(self): headers = {'Content-Type': 'text/plain; charset=utf-8'} if self.token: headers['Authorization'] = f'Bearer {self.token}' return headers
[docs] async def write(self, lines): """Write line protocol data to InfluxDB 3. :param lines: List of line protocol strings """ body = '\n'.join(lines) url = (f'{self.url}/api/v3/write_lp' f'?db={self.database}&precision={self.precision}') return await utils.HTTPRequest().getBody( url, 'POST', headers=self._headers(), data=body.encode())