Automated tool that creates and manages downsampling tasks for InfluxDB time-series databases. It detects measurements/fields in source buckets, creates downsampled copies at configurable intervals and retention periods, and generates Flux query tasks with intelligent offset scheduling.
manager/__main__.py— Entry point (python -m manager). Loads config, parses credentials, and runs the manager.manager/config.py— Configuration loading (load_config), downsample config parsing (build_bucket_configs), and source bucket parsing (parse_source_buckets) with per-measurement field filtering.manager/downsample_manager.py—DownsampleManagerclass. Orchestrates bucket/task/label creation, cleanup, and InfluxDB API interactions.manager/query_generator.py—BaseQueryGeneratorABC with two concrete variants:SourceQueryGenerator— reads from the raw source bucket; aggregates with mean/last.ChainedQueryGenerator— reads from a pre-aggregated upstream bucket; applies mean-of-means for numeric fields.
manager/model.py— Data structures:FieldData,LabelDef,DownsampleConfiguration,MeasurementConfig,SourceBucketConfig,Mappingtype alias.manager/utils.py— Helpers: deterministic hashing for offset spreading, timedelta-to-Flux-duration conversion, field filtering with fnmatch patterns.manager/__init__.py— Public API exports.
- Connect to InfluxDB (org/token/url)
- For each source bucket, query measurements and field types
- Sort downsampling configs by interval (finest first)
- Create target buckets with retention policies
- For each tier, select
SourceQueryGeneratororChainedQueryGeneratorbased on thechainedconfig flag - Generate and create/update downsampling tasks per measurement
- Label all resources for tracking
- Clean up orphaned tasks and labels
- Python 3.14+
- Uses a Python venv at
venv/in the project root - Install runtime deps:
pip install -r requirements.txt - Install runtime + test deps:
pip install -r requirements-dev.txt - Run:
python -m manager(orvenv/Scripts/python -m manageron Windows /venv/bin/python -m manageron Linux/macOS) - Run tests:
pytest tests/ -v - Lint check:
ruff check . - Format check:
ruff format --check . - Auto-fix:
ruff check --fix .andruff format .
requirements.txt— runtime deps only (installed in Docker image)requirements-dev.txt— includes runtime deps via-r requirements.txtplus test deps (pytest, ruff, testcontainers)- When adding a new dependency, pin it to a specific version (e.g.
package==1.2.3) - Put test-only packages in
requirements-dev.txt, notrequirements.txt
- Use modern Python type annotations everywhere (no
typing.Dict,typing.List— use built-indict,list,set) - Use
TypedDictwithNotRequiredfor config objects with optional fields - Use
@dataclassfor immutable value objects
- Private instance attributes prefixed with
_(e.g.self._client) - Module-level logger:
logger = logging.getLogger(__name__) - Task prefix convention:
"gen_"
- Idempotent operations:
create_or_get_*,create_or_update_*— safe to run repeatedly - Label-based resource tracking with
"creator": "influx-downsample-manager"metadata - Deterministic hashing (SHA-256) for predictable task offset spreading
- Separation of concerns: query generation, InfluxDB operations, and utilities in separate modules
- Use
json.dumps()for field lists in generated Flux - Numeric fields aggregated with
mean, non-numeric withlast - Task offsets spread via
hash_to_integerto avoid thundering herd
- Raise
Exceptionwith descriptive messages for parse failures and ownership conflicts - Log operations at INFO level (created, updated, deleted resources)
- Framework: pytest
- Tests live in
tests/and are discovered automatically - Use plain
assertstatements, notself.assertEqual/self.assertTrue - Use
@pytest.fixturefor shared setup (e.g. mockedDownsampleManager) - Use
@pytest.mark.parametrizefor data-driven tests instead of repeating test methods - Use plain classes (no
unittest.TestCaseinheritance) to group related tests - Mock InfluxDB client interactions with
unittest.mock.MagicMock/patch
This project uses Conventional Commits.
<type>(<scope>): <short summary>
| Type | Purpose |
|---|---|
feat |
New feature or capability |
fix |
Bug fix |
docs |
Documentation only |
refactor |
Code change that neither fixes a bug nor adds a feature |
test |
Adding or updating tests |
ci |
CI/CD pipeline changes |
chore |
Maintenance, deps, tooling |
perf |
Performance improvement |
manager, query, config, model, docker, ci
Append ! after the type/scope or add a BREAKING CHANGE: footer.
Always include the following trailer on AI-assisted commits:
Co-authored-by: Kiro <kiro@amazon.com>
When making changes that affect user-facing behavior, keep README.md in sync:
- Adding/removing/renaming a module under
manager/→ update the Project structure tree - Changing CLI usage, entry points, or environment variables → update Usage and Environment variables sections
- Changing the Dockerfile or Docker Compose setup → update Docker installation and usage examples
- Adding/removing Python dependencies → verify the Requirements section still matches
- Changing config schema → update Config file structure, Downsample config fields table, and the inline YAML example
- Changing the minimum Python version → update the Requirements section
Do not add sections or badges to the README unless explicitly asked. Keep it concise.
- Docker image published to
ghcr.io/xyaren/influx-downsample-managervia tag-based Release workflow python:3.14base, installs deps, runspython3 -m managerwith cron scheduling via entrypoint script
Releases are tag-driven. Pushing a semver tag (v*) triggers the Release workflow which builds and publishes a Docker image to GHCR.
- Ensure
mainis green (CI passes) git tag -a v<MAJOR>.<MINOR>.<PATCH> -m "Release v<MAJOR>.<MINOR>.<PATCH>"git push origin main --tags
.github/workflows/ci.yml— Lint (ruff), unit tests, integration tests, and Docker build on push/PR to main.github/workflows/release.yml— Tag-based (v*) Docker build and push to GHCR with semver tags
- Never commit
config.yamlwith real credentials - Do not modify files in
venv/or__pycache__/