flowsense-engine 0.4.0__tar.gz → 0.5.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/CHANGELOG.md +72 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/MANIFEST.in +1 -0
- {flowsense_engine-0.4.0/src/flowsense_engine.egg-info → flowsense_engine-0.5.1}/PKG-INFO +51 -4
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/README.md +49 -3
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/docs/architecture.md +8 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/docs/authentication.md +11 -3
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/docs/grafana.md +25 -2
- flowsense_engine-0.5.1/docs/migrating-to-0.5.md +63 -0
- flowsense_engine-0.5.1/docs/production-quickstart.md +235 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/docs/prometheus.md +8 -1
- flowsense_engine-0.5.1/docs/release-0.5.0.md +48 -0
- flowsense_engine-0.5.1/docs/release-0.5.1.md +21 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/docs/releasing.md +6 -5
- flowsense_engine-0.5.1/docs/showcase.md +79 -0
- flowsense_engine-0.5.1/examples/dags/flowsense_demo.py +48 -0
- flowsense_engine-0.5.1/examples/dags/flowsense_showcase.py +91 -0
- flowsense_engine-0.5.1/examples/python/production_batch.py +86 -0
- flowsense_engine-0.5.1/examples/python/showcase.py +290 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/pyproject.toml +21 -1
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/__init__.py +8 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/application/__init__.py +8 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/application/output.py +7 -2
- flowsense_engine-0.5.1/src/flowsense/application/policy_document.py +35 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/application/serialization.py +4 -0
- flowsense_engine-0.5.1/src/flowsense/cli/doctor.py +110 -0
- flowsense_engine-0.5.1/src/flowsense/cli/main.py +551 -0
- flowsense_engine-0.5.1/src/flowsense/cli/policy.py +103 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/domain/__init__.py +2 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/domain/enums.py +6 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/domain/policy.py +6 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/domain/results.py +3 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/engine/drift.py +16 -15
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/infrastructure/airflow/client.py +185 -35
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/infrastructure/airflow/dto.py +1 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/mcp/server.py +4 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/observability/service.py +23 -2
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1/src/flowsense_engine.egg-info}/PKG-INFO +51 -4
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense_engine.egg-info/SOURCES.txt +17 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense_engine.egg-info/requires.txt +1 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_airflow_auth.py +66 -1
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_airflow_client.py +208 -12
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_airflow_compatibility.py +1 -1
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_airflow_contract.py +2 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_airflow_resilience.py +4 -1
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_analysis_golden.py +1 -1
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_analysis_output.py +6 -0
- flowsense_engine-0.5.1/tests/test_analysis_policy_document.py +33 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_benchmark_analysis.py +1 -1
- flowsense_engine-0.5.1/tests/test_cli.py +778 -0
- flowsense_engine-0.5.1/tests/test_cli_policy.py +58 -0
- flowsense_engine-0.5.1/tests/test_doctor.py +84 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_domain.py +1 -1
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_drift.py +38 -2
- flowsense_engine-0.5.1/tests/test_examples.py +22 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_mcp_integration.py +6 -2
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_mcp_server.py +17 -3
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_package_metadata.py +1 -1
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_policy.py +34 -11
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_prometheus.py +66 -2
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_public_api.py +4 -0
- flowsense_engine-0.5.1/tests/test_showcase.py +50 -0
- flowsense_engine-0.4.0/src/flowsense/cli/main.py +0 -225
- flowsense_engine-0.4.0/tests/test_cli.py +0 -286
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/LICENSE +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/docs/alerting.md +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/docs/benchmarks.md +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/docs/migrating-to-0.3.md +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/docs/python-api.md +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/setup.cfg +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/application/analysis_engine.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/application/analyzer.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/application/batch.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/application/client.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/application/pipeline.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/application/ports.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/application/request.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/application/use_cases.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/cli/__init__.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/cli/report.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/collector/__init__.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/collector/airflow_client.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/config.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/domain/exceptions.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/domain/models.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/engine/__init__.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/engine/analyzer.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/engine/change_point.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/engine/history.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/engine/impact.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/engine/propagation.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/engine/root_cause.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/engine/timing.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/engine/trend.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/engine/validation.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/infrastructure/__init__.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/infrastructure/airflow/__init__.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/infrastructure/airflow/auth.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/infrastructure/airflow/config.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/infrastructure/airflow/exceptions.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/infrastructure/airflow/factory.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/infrastructure/airflow/mapper.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/mcp/__init__.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/models/__init__.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/models/dag_analysis.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/models/task_run.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/observability/__init__.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/observability/prometheus.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/py.typed +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/version.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense_engine.egg-info/dependency_links.txt +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense_engine.egg-info/entry_points.txt +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense_engine.egg-info/top_level.txt +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_airflow_client_integration.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_airflow_factory.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_airflow_mapper.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_analysis_pipeline.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_analysis_request.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_analysis_use_case.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_analyzer.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_architecture.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_batch_analysis_output.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_change_point.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_cli_report.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_dag_summary.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_deprecations.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_history.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_impact.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_library_client.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_observability_assets.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_observation_validation.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_propagation.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_root_cause.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_timing.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_trend.py +0 -0
|
@@ -5,6 +5,78 @@ All notable changes to FlowSense are documented in this file. The project uses
|
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
## [0.5.1] - 2026-09-25
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- Six controlled Airflow demo DAGs, each with 20 seeded runs, bounded live
|
|
19
|
+
execution waves, and a read-only execution-evidence verifier.
|
|
20
|
+
- Dedicated multi-DAG showcase dashboard with per-pipeline results and separate
|
|
21
|
+
queued/running activity metrics.
|
|
22
|
+
- FlowSense Engine wordmark in the README and PyPI package description.
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- Overview dashboard now uses instant summary queries, clearer multi-DAG labels,
|
|
27
|
+
and a shorter default history window.
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
|
|
31
|
+
- Corrected Airflow 3 GET state filters from `states` to `state`, preventing
|
|
32
|
+
running runs from shrinking the bounded successful-run analysis window.
|
|
33
|
+
|
|
34
|
+
## [0.5.0] - 2026-09-23
|
|
35
|
+
|
|
36
|
+
### Added
|
|
37
|
+
|
|
38
|
+
- Added a production quickstart and executable bounded batch-analysis example.
|
|
39
|
+
- Added `flowsense doctor` for safe configuration, Airflow API, authentication,
|
|
40
|
+
and DAG-visibility diagnostics.
|
|
41
|
+
- Added `flowsense dags` for read-only DAG discovery with table and JSON output.
|
|
42
|
+
- Added `flowsense analyze-batch` for bounded multi-DAG CLI analysis with the
|
|
43
|
+
versioned batch JSON contract.
|
|
44
|
+
- Added severity-based CI exit thresholds to batch analysis.
|
|
45
|
+
- Added full analysis-policy configuration to the batch CLI.
|
|
46
|
+
- Added bounded DAG discovery to batch analysis with `--all-dags`,
|
|
47
|
+
`--dag-limit`, and optional paused-DAG inclusion.
|
|
48
|
+
- Added CLI access to the versioned batch output JSON Schema through
|
|
49
|
+
`flowsense schema --document batch`.
|
|
50
|
+
- Added reliable versioned JSON file output to single-DAG analysis through
|
|
51
|
+
`flowsense analyze --output-file`.
|
|
52
|
+
- Added reusable, versioned JSON analysis policies for single and batch CLI
|
|
53
|
+
commands, with explicit command-line overrides and JSON Schema export.
|
|
54
|
+
- Added versioned analysis-policy support to the optional Prometheus metrics
|
|
55
|
+
command and propagated the selected policy through every collection cycle.
|
|
56
|
+
- Added a validated per-cycle history limit to the Prometheus metrics command
|
|
57
|
+
so Airflow collection remains explicitly bounded.
|
|
58
|
+
- Added expanded Ruff quality rules, a 90% CI coverage gate, and graceful MCP
|
|
59
|
+
test skipping when the optional dependency is not installed.
|
|
60
|
+
- Reduced Airflow collection overhead with bounded server-side DAG run filters
|
|
61
|
+
and batched task-instance retrieval, including compatibility fallbacks for
|
|
62
|
+
deployments that do not support the optimized endpoints.
|
|
63
|
+
- Added explicit drift direction and effective MAD fields to analysis results,
|
|
64
|
+
plus configurable relative and absolute dispersion floors.
|
|
65
|
+
|
|
66
|
+
### Changed
|
|
67
|
+
|
|
68
|
+
- Airflow login tokens are now refreshed once after an unauthorized API
|
|
69
|
+
response, while static bearer, Basic, and custom authentication lifecycles
|
|
70
|
+
remain application-owned.
|
|
71
|
+
- Advanced the analysis output schema to version `1.2` for the new drift and
|
|
72
|
+
policy fields.
|
|
73
|
+
|
|
74
|
+
### Fixed
|
|
75
|
+
|
|
76
|
+
- Constant and near-constant baselines no longer classify negligible timing
|
|
77
|
+
noise as an automatic critical anomaly when raw MAD is zero or extremely
|
|
78
|
+
small.
|
|
79
|
+
|
|
8
80
|
## [0.4.0] - 2026-09-20
|
|
9
81
|
|
|
10
82
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flowsense-engine
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.1
|
|
4
4
|
Summary: Temporal drift and anomaly detection for Apache Airflow
|
|
5
5
|
Author: Omer Cengiz
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -28,6 +28,7 @@ Provides-Extra: dev
|
|
|
28
28
|
Requires-Dist: build>=1.2; extra == "dev"
|
|
29
29
|
Requires-Dist: pyright>=1.1.400; extra == "dev"
|
|
30
30
|
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
31
|
+
Requires-Dist: pytest-cov>=5.0; extra == "dev"
|
|
31
32
|
Requires-Dist: ruff>=0.6; extra == "dev"
|
|
32
33
|
Provides-Extra: mcp
|
|
33
34
|
Requires-Dist: mcp[cli]>=2.0; extra == "mcp"
|
|
@@ -35,12 +36,18 @@ Dynamic: license-file
|
|
|
35
36
|
|
|
36
37
|
# FlowSense Engine
|
|
37
38
|
|
|
39
|
+
<p align="center">
|
|
40
|
+
<img src="https://raw.githubusercontent.com/omercengiz/flowsense-engine/27f7db5e55bfefbba6e355c53c7c84ff34e6f37b/assets/branding/flowsense-engine-logo-v2.png" alt="FlowSense Engine logo" width="640">
|
|
41
|
+
</p>
|
|
42
|
+
|
|
38
43
|
Temporal drift, anomaly detection, and dependency-aware propagation analysis for Apache Airflow.
|
|
39
44
|
|
|
40
|
-
Current package release: `0.
|
|
45
|
+
Current package release: `0.5.1`. See [CHANGELOG.md](CHANGELOG.md) for release
|
|
41
46
|
notes, [docs/architecture.md](docs/architecture.md) for the system architecture,
|
|
42
47
|
[docs/benchmarks.md](docs/benchmarks.md) for performance measurement, and
|
|
43
|
-
[docs/
|
|
48
|
+
[docs/production-quickstart.md](docs/production-quickstart.md) for a production
|
|
49
|
+
walkthrough. See [docs/migrating-to-0.5.md](docs/migrating-to-0.5.md) for the
|
|
50
|
+
current migration guidance.
|
|
44
51
|
Maintainers can use [docs/releasing.md](docs/releasing.md) as the release checklist.
|
|
45
52
|
|
|
46
53
|
FlowSense analyzes historical DAG executions to identify abnormal task behavior and trace how anomalies propagate through downstream dependencies.
|
|
@@ -153,6 +160,9 @@ Once published on PyPI, install the distribution with:
|
|
|
153
160
|
pip install flowsense-engine
|
|
154
161
|
```
|
|
155
162
|
|
|
163
|
+
For an end-to-end Airflow setup, follow the
|
|
164
|
+
[production quickstart](docs/production-quickstart.md).
|
|
165
|
+
|
|
156
166
|
The distribution name is `flowsense-engine`; Python imports and CLI commands
|
|
157
167
|
remain `flowsense`.
|
|
158
168
|
|
|
@@ -218,9 +228,15 @@ export $(grep -v '^#' .env | xargs)
|
|
|
218
228
|
Then run:
|
|
219
229
|
|
|
220
230
|
```bash
|
|
231
|
+
flowsense doctor
|
|
232
|
+
flowsense dags
|
|
221
233
|
flowsense analyze <dag_id>
|
|
234
|
+
flowsense analyze-batch <dag_id> [<dag_id> ...]
|
|
222
235
|
```
|
|
223
236
|
|
|
237
|
+
Both single and batch analysis commands support `--fail-on` for CI severity
|
|
238
|
+
gates.
|
|
239
|
+
|
|
224
240
|
The CLI report includes a DAG summary and separate tables for task drift,
|
|
225
241
|
handoff drift, change points, trends, propagation paths, and diagnostics.
|
|
226
242
|
Results are ordered by severity or subject so repeated analyses remain easy to
|
|
@@ -230,14 +246,30 @@ For automation and CI/CD integrations, request the versioned JSON document:
|
|
|
230
246
|
|
|
231
247
|
```bash
|
|
232
248
|
flowsense analyze <dag_id> --output json
|
|
249
|
+
flowsense analyze <dag_id> --output-file flowsense-analysis.json
|
|
233
250
|
```
|
|
234
251
|
|
|
252
|
+
`--output-file` always writes the versioned JSON contract and avoids relying on
|
|
253
|
+
shell redirection in CI jobs.
|
|
254
|
+
|
|
235
255
|
CI jobs can also fail when the analysis reaches a selected severity:
|
|
236
256
|
|
|
237
257
|
```bash
|
|
238
258
|
flowsense analyze <dag_id> --output json --fail-on high
|
|
239
259
|
```
|
|
240
260
|
|
|
261
|
+
Store reusable analysis settings in a versioned JSON policy file and share it
|
|
262
|
+
between single and batch analysis:
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
flowsense analyze <dag_id> --policy-file flowsense-policy.json
|
|
266
|
+
flowsense analyze-batch --all-dags --dag-limit 10 \
|
|
267
|
+
--policy-file flowsense-policy.json
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
Explicit policy options override values loaded from the file. Generate its JSON
|
|
271
|
+
Schema with `flowsense schema --document policy`.
|
|
272
|
+
|
|
241
273
|
`--fail-on` accepts `medium`, `high`, or `critical`. The report is always
|
|
242
274
|
written before FlowSense exits: code `0` means the severity is below the
|
|
243
275
|
threshold, code `2` means the threshold was reached, and code `1` remains
|
|
@@ -265,6 +297,8 @@ flowsense analyze <dag_id> --dag-run-id <dag_run_id>
|
|
|
265
297
|
|
|
266
298
|
The MCP tool exposes the same option as `dag_run_id`. Analysis output includes
|
|
267
299
|
`current_dag_run_id`; this field was introduced in output schema version `1.1`.
|
|
300
|
+
Output schema version `1.2` adds drift `direction`, the regularized
|
|
301
|
+
`effective_mad`, and the dispersion-floor policy values.
|
|
268
302
|
|
|
269
303
|
The JSON document and MCP tool response share the same serialization contract
|
|
270
304
|
and include a `schema_version` field. The serializer is also available from the
|
|
@@ -279,8 +313,13 @@ The same schema can be emitted without connecting to Airflow:
|
|
|
279
313
|
|
|
280
314
|
```bash
|
|
281
315
|
flowsense schema > flowsense-analysis.schema.json
|
|
316
|
+
flowsense schema --document batch > flowsense-batch.schema.json
|
|
282
317
|
```
|
|
283
318
|
|
|
319
|
+
The default remains the single-DAG analysis schema. Use `--document batch` to
|
|
320
|
+
emit the versioned batch envelope schema, including successful analyses and
|
|
321
|
+
per-DAG failure records.
|
|
322
|
+
|
|
284
323
|
This output is deterministic and can be used in CI contract checks, editor
|
|
285
324
|
tooling, or client code generation.
|
|
286
325
|
|
|
@@ -332,6 +371,8 @@ policy = AnalysisPolicy(
|
|
|
332
371
|
medium_threshold=2.5,
|
|
333
372
|
high_threshold=4.0,
|
|
334
373
|
critical_threshold=6.0,
|
|
374
|
+
minimum_relative_dispersion=0.01,
|
|
375
|
+
minimum_absolute_dispersion=0.001,
|
|
335
376
|
mapped_task_aggregation=MappedTaskAggregation.MAX,
|
|
336
377
|
change_point_minimum_segment_size=4,
|
|
337
378
|
change_point_score_threshold=4.0,
|
|
@@ -344,6 +385,8 @@ policy = AnalysisPolicy(
|
|
|
344
385
|
`baseline_window` limits the number of historical values used before the current
|
|
345
386
|
run. Mapped task durations can be aggregated with `MAX`, `MEAN`, or `SUM`. The
|
|
346
387
|
same policy options are available through the CLI and MCP tool.
|
|
388
|
+
The dispersion floors prevent constant or nearly constant baselines from
|
|
389
|
+
turning negligible timing noise into an automatic critical anomaly.
|
|
347
390
|
Change-point and trend detection can also be disabled independently with
|
|
348
391
|
`change_point_detection_enabled=False` or `trend_detection_enabled=False`.
|
|
349
392
|
|
|
@@ -383,7 +426,11 @@ information for a DAG.
|
|
|
383
426
|
Run continuous analysis and expose the latest DAG and bounded task-level metrics:
|
|
384
427
|
|
|
385
428
|
```bash
|
|
386
|
-
flowsense serve-metrics example_dag
|
|
429
|
+
flowsense serve-metrics example_dag \
|
|
430
|
+
--host 0.0.0.0 \
|
|
431
|
+
--port 9108 \
|
|
432
|
+
--history-run-limit 50 \
|
|
433
|
+
--policy-file flowsense-policy.json
|
|
387
434
|
```
|
|
388
435
|
|
|
389
436
|
See [docs/prometheus.md](docs/prometheus.md) for the metric contract,
|
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
# FlowSense Engine
|
|
2
2
|
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img src="https://raw.githubusercontent.com/omercengiz/flowsense-engine/27f7db5e55bfefbba6e355c53c7c84ff34e6f37b/assets/branding/flowsense-engine-logo-v2.png" alt="FlowSense Engine logo" width="640">
|
|
5
|
+
</p>
|
|
6
|
+
|
|
3
7
|
Temporal drift, anomaly detection, and dependency-aware propagation analysis for Apache Airflow.
|
|
4
8
|
|
|
5
|
-
Current package release: `0.
|
|
9
|
+
Current package release: `0.5.1`. See [CHANGELOG.md](CHANGELOG.md) for release
|
|
6
10
|
notes, [docs/architecture.md](docs/architecture.md) for the system architecture,
|
|
7
11
|
[docs/benchmarks.md](docs/benchmarks.md) for performance measurement, and
|
|
8
|
-
[docs/
|
|
12
|
+
[docs/production-quickstart.md](docs/production-quickstart.md) for a production
|
|
13
|
+
walkthrough. See [docs/migrating-to-0.5.md](docs/migrating-to-0.5.md) for the
|
|
14
|
+
current migration guidance.
|
|
9
15
|
Maintainers can use [docs/releasing.md](docs/releasing.md) as the release checklist.
|
|
10
16
|
|
|
11
17
|
FlowSense analyzes historical DAG executions to identify abnormal task behavior and trace how anomalies propagate through downstream dependencies.
|
|
@@ -118,6 +124,9 @@ Once published on PyPI, install the distribution with:
|
|
|
118
124
|
pip install flowsense-engine
|
|
119
125
|
```
|
|
120
126
|
|
|
127
|
+
For an end-to-end Airflow setup, follow the
|
|
128
|
+
[production quickstart](docs/production-quickstart.md).
|
|
129
|
+
|
|
121
130
|
The distribution name is `flowsense-engine`; Python imports and CLI commands
|
|
122
131
|
remain `flowsense`.
|
|
123
132
|
|
|
@@ -183,9 +192,15 @@ export $(grep -v '^#' .env | xargs)
|
|
|
183
192
|
Then run:
|
|
184
193
|
|
|
185
194
|
```bash
|
|
195
|
+
flowsense doctor
|
|
196
|
+
flowsense dags
|
|
186
197
|
flowsense analyze <dag_id>
|
|
198
|
+
flowsense analyze-batch <dag_id> [<dag_id> ...]
|
|
187
199
|
```
|
|
188
200
|
|
|
201
|
+
Both single and batch analysis commands support `--fail-on` for CI severity
|
|
202
|
+
gates.
|
|
203
|
+
|
|
189
204
|
The CLI report includes a DAG summary and separate tables for task drift,
|
|
190
205
|
handoff drift, change points, trends, propagation paths, and diagnostics.
|
|
191
206
|
Results are ordered by severity or subject so repeated analyses remain easy to
|
|
@@ -195,14 +210,30 @@ For automation and CI/CD integrations, request the versioned JSON document:
|
|
|
195
210
|
|
|
196
211
|
```bash
|
|
197
212
|
flowsense analyze <dag_id> --output json
|
|
213
|
+
flowsense analyze <dag_id> --output-file flowsense-analysis.json
|
|
198
214
|
```
|
|
199
215
|
|
|
216
|
+
`--output-file` always writes the versioned JSON contract and avoids relying on
|
|
217
|
+
shell redirection in CI jobs.
|
|
218
|
+
|
|
200
219
|
CI jobs can also fail when the analysis reaches a selected severity:
|
|
201
220
|
|
|
202
221
|
```bash
|
|
203
222
|
flowsense analyze <dag_id> --output json --fail-on high
|
|
204
223
|
```
|
|
205
224
|
|
|
225
|
+
Store reusable analysis settings in a versioned JSON policy file and share it
|
|
226
|
+
between single and batch analysis:
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
flowsense analyze <dag_id> --policy-file flowsense-policy.json
|
|
230
|
+
flowsense analyze-batch --all-dags --dag-limit 10 \
|
|
231
|
+
--policy-file flowsense-policy.json
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Explicit policy options override values loaded from the file. Generate its JSON
|
|
235
|
+
Schema with `flowsense schema --document policy`.
|
|
236
|
+
|
|
206
237
|
`--fail-on` accepts `medium`, `high`, or `critical`. The report is always
|
|
207
238
|
written before FlowSense exits: code `0` means the severity is below the
|
|
208
239
|
threshold, code `2` means the threshold was reached, and code `1` remains
|
|
@@ -230,6 +261,8 @@ flowsense analyze <dag_id> --dag-run-id <dag_run_id>
|
|
|
230
261
|
|
|
231
262
|
The MCP tool exposes the same option as `dag_run_id`. Analysis output includes
|
|
232
263
|
`current_dag_run_id`; this field was introduced in output schema version `1.1`.
|
|
264
|
+
Output schema version `1.2` adds drift `direction`, the regularized
|
|
265
|
+
`effective_mad`, and the dispersion-floor policy values.
|
|
233
266
|
|
|
234
267
|
The JSON document and MCP tool response share the same serialization contract
|
|
235
268
|
and include a `schema_version` field. The serializer is also available from the
|
|
@@ -244,8 +277,13 @@ The same schema can be emitted without connecting to Airflow:
|
|
|
244
277
|
|
|
245
278
|
```bash
|
|
246
279
|
flowsense schema > flowsense-analysis.schema.json
|
|
280
|
+
flowsense schema --document batch > flowsense-batch.schema.json
|
|
247
281
|
```
|
|
248
282
|
|
|
283
|
+
The default remains the single-DAG analysis schema. Use `--document batch` to
|
|
284
|
+
emit the versioned batch envelope schema, including successful analyses and
|
|
285
|
+
per-DAG failure records.
|
|
286
|
+
|
|
249
287
|
This output is deterministic and can be used in CI contract checks, editor
|
|
250
288
|
tooling, or client code generation.
|
|
251
289
|
|
|
@@ -297,6 +335,8 @@ policy = AnalysisPolicy(
|
|
|
297
335
|
medium_threshold=2.5,
|
|
298
336
|
high_threshold=4.0,
|
|
299
337
|
critical_threshold=6.0,
|
|
338
|
+
minimum_relative_dispersion=0.01,
|
|
339
|
+
minimum_absolute_dispersion=0.001,
|
|
300
340
|
mapped_task_aggregation=MappedTaskAggregation.MAX,
|
|
301
341
|
change_point_minimum_segment_size=4,
|
|
302
342
|
change_point_score_threshold=4.0,
|
|
@@ -309,6 +349,8 @@ policy = AnalysisPolicy(
|
|
|
309
349
|
`baseline_window` limits the number of historical values used before the current
|
|
310
350
|
run. Mapped task durations can be aggregated with `MAX`, `MEAN`, or `SUM`. The
|
|
311
351
|
same policy options are available through the CLI and MCP tool.
|
|
352
|
+
The dispersion floors prevent constant or nearly constant baselines from
|
|
353
|
+
turning negligible timing noise into an automatic critical anomaly.
|
|
312
354
|
Change-point and trend detection can also be disabled independently with
|
|
313
355
|
`change_point_detection_enabled=False` or `trend_detection_enabled=False`.
|
|
314
356
|
|
|
@@ -348,7 +390,11 @@ information for a DAG.
|
|
|
348
390
|
Run continuous analysis and expose the latest DAG and bounded task-level metrics:
|
|
349
391
|
|
|
350
392
|
```bash
|
|
351
|
-
flowsense serve-metrics example_dag
|
|
393
|
+
flowsense serve-metrics example_dag \
|
|
394
|
+
--host 0.0.0.0 \
|
|
395
|
+
--port 9108 \
|
|
396
|
+
--history-run-limit 50 \
|
|
397
|
+
--policy-file flowsense-policy.json
|
|
352
398
|
```
|
|
353
399
|
|
|
354
400
|
See [docs/prometheus.md](docs/prometheus.md) for the metric contract,
|
|
@@ -81,6 +81,14 @@ Authentication is supplied through `AirflowAuthProvider`. Built-in providers
|
|
|
81
81
|
cover Basic Auth, Airflow login-token exchange, static bearer tokens, and custom
|
|
82
82
|
headers without coupling request collection to a deployment's identity system.
|
|
83
83
|
|
|
84
|
+
Collection is bounded at the Airflow API boundary whenever the configured API
|
|
85
|
+
supports it. Airflow 2 uses the stable batch POST endpoints, while Airflow 3
|
|
86
|
+
uses filtered collection endpoints for successful DAG runs and task instances.
|
|
87
|
+
Unsupported filter or batch responses fall back to the paginated per-run API,
|
|
88
|
+
preserving compatibility with older Airflow 2 deployments. This optimization
|
|
89
|
+
belongs exclusively to the infrastructure adapter and does not leak transport
|
|
90
|
+
capabilities into application or domain contracts.
|
|
91
|
+
|
|
84
92
|
### Delivery adapters
|
|
85
93
|
|
|
86
94
|
`flowsense.cli`, `flowsense.mcp`, and `flowsense.observability` translate user input into an
|
|
@@ -16,8 +16,11 @@ AIRFLOW_USERNAME=airflow
|
|
|
16
16
|
AIRFLOW_PASSWORD=secret
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
FlowSense exchanges the credentials
|
|
20
|
-
|
|
19
|
+
FlowSense exchanges the credentials and caches the returned bearer token for
|
|
20
|
+
the lifetime of the client. If an Airflow API request returns `401`, FlowSense
|
|
21
|
+
invalidates a login-issued token, obtains a fresh token, and retries that API
|
|
22
|
+
request once. A second `401` is returned as `AirflowApiError`; it is never
|
|
23
|
+
retried indefinitely.
|
|
21
24
|
|
|
22
25
|
### Basic authentication
|
|
23
26
|
|
|
@@ -42,6 +45,9 @@ AIRFLOW_BEARER_TOKEN=secret-token
|
|
|
42
45
|
Username and password are not required in bearer mode. Secrets are excluded
|
|
43
46
|
from the `AirflowConfig` representation, but applications must still keep them
|
|
44
47
|
out of logs, shell history, source control, and command-line arguments.
|
|
48
|
+
Static bearer tokens are not automatically replaced after `401`; their
|
|
49
|
+
lifecycle remains owned by the application or identity provider that issued
|
|
50
|
+
them.
|
|
45
51
|
|
|
46
52
|
## Custom provider
|
|
47
53
|
|
|
@@ -74,4 +80,6 @@ provider = BearerTokenAuthProvider(load_current_token)
|
|
|
74
80
|
|
|
75
81
|
Custom providers should return only authentication material and leave request
|
|
76
82
|
execution, retry, timeout, payload validation, and error translation to
|
|
77
|
-
`AirflowClient`.
|
|
83
|
+
`AirflowClient`. A `401` from a custom provider is not interpreted as permission
|
|
84
|
+
to rotate external credentials; the owning application decides how to refresh
|
|
85
|
+
them.
|
|
@@ -12,9 +12,13 @@ Configure the required `AIRFLOW_*` environment variables, then run:
|
|
|
12
12
|
flowsense serve-metrics example_dag another_dag \
|
|
13
13
|
--host 0.0.0.0 \
|
|
14
14
|
--port 9108 \
|
|
15
|
-
--interval-seconds 60
|
|
15
|
+
--interval-seconds 60 \
|
|
16
|
+
--history-run-limit 50 \
|
|
17
|
+
--policy-file flowsense-policy.json
|
|
16
18
|
```
|
|
17
19
|
|
|
20
|
+
Omit `--policy-file` to use the default analysis policy.
|
|
21
|
+
|
|
18
22
|
Binding to `0.0.0.0` makes the endpoint reachable from the local Prometheus
|
|
19
23
|
container. Do not expose this port to untrusted networks without an appropriate
|
|
20
24
|
network policy or reverse proxy.
|
|
@@ -52,7 +56,21 @@ The dashboard provides:
|
|
|
52
56
|
- currently firing FlowSense alerts.
|
|
53
57
|
|
|
54
58
|
Use the DAG and task variables at the top of the dashboard to narrow the view.
|
|
55
|
-
The default time range is
|
|
59
|
+
The default time range is 15 minutes and the dashboard refreshes every 30 seconds.
|
|
60
|
+
Summary cards use instant queries, so they remain populated independently of
|
|
61
|
+
the selected history window. Current task comparisons include both DAG and
|
|
62
|
+
task names to distinguish tasks across multiple DAGs.
|
|
63
|
+
|
|
64
|
+
The top row summarizes the selected DAGs: monitored count, highest severity,
|
|
65
|
+
analysis health (healthy only when every selected DAG succeeded), mean coverage,
|
|
66
|
+
and total anomalous and affected tasks. Task comparisons and history appear
|
|
67
|
+
below; collection diagnostics and active alerts follow.
|
|
68
|
+
|
|
69
|
+
Prometheus history starts when the metrics service is scraped; historical
|
|
70
|
+
Airflow runs are analyzed but are not backfilled into these charts. After
|
|
71
|
+
starting the exporter, use a recent time range and allow a few scrapes. An
|
|
72
|
+
existing browser URL can retain an older time range; select Last 15 minutes
|
|
73
|
+
manually in that case.
|
|
56
74
|
See [alerting.md](alerting.md) for rule behavior, validation, and production
|
|
57
75
|
notification configuration.
|
|
58
76
|
|
|
@@ -64,3 +82,8 @@ docker compose -f deploy/observability/docker-compose.yml down
|
|
|
64
82
|
|
|
65
83
|
Prometheus and Grafana data remain in named volumes. To explicitly remove those
|
|
66
84
|
local volumes, add `--volumes` to the command.
|
|
85
|
+
|
|
86
|
+
## Multi-DAG demo with execution evidence
|
|
87
|
+
|
|
88
|
+
For six real Airflow workloads, 20 seeded runs per DAG, continued live activity,
|
|
89
|
+
and a dedicated presentation dashboard, see [showcase.md](showcase.md).
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Migrating to FlowSense 0.5
|
|
2
|
+
|
|
3
|
+
FlowSense 0.5 improves production-scale Airflow collection, authentication
|
|
4
|
+
resilience, and statistical drift accuracy. Existing Python, CLI, and MCP entry
|
|
5
|
+
points remain available, but JSON consumers must account for analysis output
|
|
6
|
+
schema version `1.2`.
|
|
7
|
+
|
|
8
|
+
## Analysis output schema 1.2
|
|
9
|
+
|
|
10
|
+
Each task and handoff drift result now includes:
|
|
11
|
+
|
|
12
|
+
- `direction`: `INCREASE`, `DECREASE`, or `UNCHANGED`;
|
|
13
|
+
- `effective_mad`: the regularized dispersion used to calculate the robust
|
|
14
|
+
z-score.
|
|
15
|
+
|
|
16
|
+
The embedded policy also includes `minimum_relative_dispersion` and
|
|
17
|
+
`minimum_absolute_dispersion`. Consumers that validate JSON should regenerate
|
|
18
|
+
their model or schema with:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
flowsense schema --document analysis
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
The batch envelope remains at schema version `1.0`; each successful analysis
|
|
25
|
+
inside it now uses schema version `1.2`.
|
|
26
|
+
|
|
27
|
+
## Drift behavior
|
|
28
|
+
|
|
29
|
+
Raw MAD is still reported without modification. Score calculation now uses the
|
|
30
|
+
largest of raw MAD, the configured relative floor, and the configured absolute
|
|
31
|
+
floor. This prevents negligible timing noise on constant baselines from being
|
|
32
|
+
classified as an automatic critical anomaly.
|
|
33
|
+
|
|
34
|
+
The defaults are:
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"minimum_relative_dispersion": 0.01,
|
|
39
|
+
"minimum_absolute_dispersion": 0.001
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Pin explicit values in a policy file if existing alert thresholds were tuned
|
|
44
|
+
around the previous zero-MAD behavior.
|
|
45
|
+
|
|
46
|
+
## Airflow collection and authentication
|
|
47
|
+
|
|
48
|
+
Recent successful DAG runs and task instances use bounded or batch API calls
|
|
49
|
+
when supported. Older Airflow deployments automatically fall back to the
|
|
50
|
+
paginated per-run endpoints.
|
|
51
|
+
|
|
52
|
+
Airflow login tokens obtained through `AIRFLOW_AUTH_MODE=token` are refreshed
|
|
53
|
+
once after a `401` response. Basic, static bearer, and custom authentication
|
|
54
|
+
providers retain application-owned credential lifecycles.
|
|
55
|
+
|
|
56
|
+
## Validation checklist
|
|
57
|
+
|
|
58
|
+
1. Regenerate and compare the analysis JSON Schema.
|
|
59
|
+
2. Validate alerting against representative historical DAG runs.
|
|
60
|
+
3. Confirm the configured Airflow identity can use batch endpoints or fallback
|
|
61
|
+
endpoints.
|
|
62
|
+
4. Run `flowsense doctor` against the target Airflow environment.
|
|
63
|
+
5. Perform a canary analysis before replacing a pinned 0.4 installation.
|