diff --git a/influxdata-plugin-utils/CHANGELOG.md b/influxdata-plugin-utils/CHANGELOG.md index ac17e36..6af573f 100644 --- a/influxdata-plugin-utils/CHANGELOG.md +++ b/influxdata-plugin-utils/CHANGELOG.md @@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.2.0] - 2026-07-12 + +### Added + +- `write.write_data` — optional `database` parameter for writing to another + database. +- `parsing.parse_timedelta` — `ms` (milliseconds) and `us` (microseconds) + duration units. + +### Changed + +- `write.write_data` — `no_sync` now defaults to `None`: writes go through + `write` / `write_to_db` (available on all InfluxDB 3 versions); passing a + boolean switches to `write_sync` / `write_sync_to_db` (InfluxDB 3.8+). + ## [0.1.0] - 2026-07-08 ### Added @@ -22,5 +37,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `write` — `build_line`, `build_line_typed`, `add_field_with_type`, `write_data` (batching + retry), `BatchLines`. -[Unreleased]: https://github.com/influxdata/influxdb3_plugins/compare/utils-v0.1.0...HEAD +[Unreleased]: https://github.com/influxdata/influxdb3_plugins/compare/utils-v0.2.0...HEAD +[0.2.0]: https://github.com/influxdata/influxdb3_plugins/compare/utils-v0.1.0...utils-v0.2.0 [0.1.0]: https://github.com/influxdata/influxdb3_plugins/releases/tag/utils-v0.1.0 \ No newline at end of file diff --git a/influxdata-plugin-utils/README.md b/influxdata-plugin-utils/README.md index 5d6b94c..7b88099 100644 --- a/influxdata-plugin-utils/README.md +++ b/influxdata-plugin-utils/README.md @@ -65,6 +65,8 @@ lines = [ ] write_data(influxdb3_local, lines) # batched + retried by default # write_data(influxdb3_local, lines, batch=False, retries=0) # opt out +# write_data(influxdb3_local, lines, database="other_db") # another database +# write_data(influxdb3_local, lines, no_sync=True) # write_sync API (3.8+) ``` ## License diff --git a/influxdata-plugin-utils/src/influxdata_plugin_utils/__init__.py b/influxdata-plugin-utils/src/influxdata_plugin_utils/__init__.py index d952c6b..ee41c7b 100644 --- a/influxdata-plugin-utils/src/influxdata_plugin_utils/__init__.py +++ b/influxdata-plugin-utils/src/influxdata_plugin_utils/__init__.py @@ -8,7 +8,7 @@ write - LineBuilder builders and resilient write_data """ -__version__ = "0.1.0" +__version__ = "0.2.0" from . import cache, config, introspection, parsing, write from .cache import cached diff --git a/influxdata-plugin-utils/src/influxdata_plugin_utils/parsing.py b/influxdata-plugin-utils/src/influxdata_plugin_utils/parsing.py index bbc30f2..47e4deb 100644 --- a/influxdata-plugin-utils/src/influxdata_plugin_utils/parsing.py +++ b/influxdata-plugin-utils/src/influxdata_plugin_utils/parsing.py @@ -19,6 +19,8 @@ _DURATION_RE = re.compile(r"^\s*(\d+)\s*([a-zA-Z]+)\s*$") _DURATION_UNITS = { + "us": "microseconds", + "ms": "milliseconds", "s": "seconds", "min": "minutes", "h": "hours", @@ -33,7 +35,7 @@ def parse_timedelta(raw) -> timedelta: - """Parse a duration like ``30s``, ``5min``, ``1h``, ``2d``, ``1w``.""" + """Parse a duration like ``500us``, ``100ms``, ``30s``, ``5min``, ``1h``, ``2d``, ``1w``.""" if isinstance(raw, timedelta): return raw match = _DURATION_RE.match(str(raw)) diff --git a/influxdata-plugin-utils/src/influxdata_plugin_utils/write.py b/influxdata-plugin-utils/src/influxdata_plugin_utils/write.py index ead98e0..cca62ab 100644 --- a/influxdata-plugin-utils/src/influxdata_plugin_utils/write.py +++ b/influxdata-plugin-utils/src/influxdata_plugin_utils/write.py @@ -9,6 +9,7 @@ import math import random import time +from functools import partial from .parsing import parse_bool @@ -160,7 +161,8 @@ def write_data( batch: bool = True, retries: int = 3, base_delay: float = 1.0, - no_sync: bool = True, + no_sync: bool | None = None, + database: str | None = None, ) -> None: """Write LineBuilder objects with optional batching and retry. @@ -170,8 +172,17 @@ def write_data( batch: Combine all lines into one payload via :class:`BatchLines`. Set ``False`` to write each line individually. retries: Number of extra attempts on failure (``0`` disables retry). + Effective only when ``no_sync`` is set: the default buffered + ``write`` / ``write_to_db`` never raise at call time. base_delay: Base seconds for exponential backoff with jitter. - no_sync: Passed through to ``write_sync``. + no_sync: When set, writes go through ``write_sync`` / + ``write_sync_to_db`` with this flag (requires InfluxDB 3.8+), + which write immediately and raise on failure. When ``None`` + (default), the universally available ``write`` / ``write_to_db`` + are used: they only queue lines that are flushed after plugin + execution completes, so failures are not reported to the caller. + database: Target database; when ``None``, writes to the trigger's + database. """ builders = [builder for builder in line_builders if builder is not None] if not builders: @@ -180,10 +191,20 @@ def write_data( payloads = [BatchLines(builders)] if batch else builders attempts = max(retries, 0) + 1 + if no_sync is None: + if database: + write_fn = partial(influxdb3_local.write_to_db, database) + else: + write_fn = influxdb3_local.write + elif database: + write_fn = partial(influxdb3_local.write_sync_to_db, database, no_sync=no_sync) + else: + write_fn = partial(influxdb3_local.write_sync, no_sync=no_sync) + for payload in payloads: for attempt in range(attempts): try: - influxdb3_local.write_sync(payload, no_sync=no_sync) + write_fn(payload) break except Exception: if attempt == attempts - 1: