flowsense-engine 0.4.0__tar.gz → 0.5.0__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.0}/CHANGELOG.md +52 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/MANIFEST.in +1 -0
- {flowsense_engine-0.4.0/src/flowsense_engine.egg-info → flowsense_engine-0.5.0}/PKG-INFO +47 -4
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/README.md +45 -3
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/docs/architecture.md +8 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/docs/authentication.md +11 -3
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/docs/grafana.md +5 -1
- flowsense_engine-0.5.0/docs/migrating-to-0.5.md +63 -0
- flowsense_engine-0.5.0/docs/production-quickstart.md +235 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/docs/prometheus.md +8 -1
- flowsense_engine-0.5.0/docs/release-0.5.0.md +48 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/docs/releasing.md +6 -5
- flowsense_engine-0.5.0/examples/dags/flowsense_demo.py +48 -0
- flowsense_engine-0.5.0/examples/python/production_batch.py +86 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/pyproject.toml +21 -1
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/__init__.py +8 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/application/__init__.py +8 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/application/output.py +7 -2
- flowsense_engine-0.5.0/src/flowsense/application/policy_document.py +35 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/application/serialization.py +4 -0
- flowsense_engine-0.5.0/src/flowsense/cli/doctor.py +110 -0
- flowsense_engine-0.5.0/src/flowsense/cli/main.py +551 -0
- flowsense_engine-0.5.0/src/flowsense/cli/policy.py +103 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/domain/__init__.py +2 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/domain/enums.py +6 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/domain/policy.py +6 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/domain/results.py +3 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/engine/drift.py +16 -15
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/infrastructure/airflow/client.py +185 -35
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/infrastructure/airflow/dto.py +1 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/mcp/server.py +4 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/observability/service.py +23 -2
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0/src/flowsense_engine.egg-info}/PKG-INFO +47 -4
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense_engine.egg-info/SOURCES.txt +12 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense_engine.egg-info/requires.txt +1 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_airflow_auth.py +66 -1
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_airflow_client.py +177 -12
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_airflow_compatibility.py +1 -1
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_airflow_contract.py +2 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_airflow_resilience.py +4 -1
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_analysis_golden.py +1 -1
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_analysis_output.py +6 -0
- flowsense_engine-0.5.0/tests/test_analysis_policy_document.py +33 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_benchmark_analysis.py +1 -1
- flowsense_engine-0.5.0/tests/test_cli.py +778 -0
- flowsense_engine-0.5.0/tests/test_cli_policy.py +58 -0
- flowsense_engine-0.5.0/tests/test_doctor.py +84 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_domain.py +1 -1
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_drift.py +38 -2
- flowsense_engine-0.5.0/tests/test_examples.py +22 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_mcp_integration.py +6 -2
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_mcp_server.py +17 -3
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_package_metadata.py +1 -1
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_policy.py +34 -11
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_prometheus.py +66 -2
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_public_api.py +4 -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.0}/LICENSE +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/docs/alerting.md +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/docs/benchmarks.md +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/docs/migrating-to-0.3.md +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/docs/python-api.md +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/setup.cfg +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/application/analysis_engine.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/application/analyzer.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/application/batch.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/application/client.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/application/pipeline.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/application/ports.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/application/request.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/application/use_cases.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/cli/__init__.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/cli/report.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/collector/__init__.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/collector/airflow_client.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/config.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/domain/exceptions.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/domain/models.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/engine/__init__.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/engine/analyzer.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/engine/change_point.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/engine/history.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/engine/impact.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/engine/propagation.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/engine/root_cause.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/engine/timing.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/engine/trend.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/engine/validation.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/infrastructure/__init__.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/infrastructure/airflow/__init__.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/infrastructure/airflow/auth.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/infrastructure/airflow/config.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/infrastructure/airflow/exceptions.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/infrastructure/airflow/factory.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/infrastructure/airflow/mapper.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/mcp/__init__.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/models/__init__.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/models/dag_analysis.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/models/task_run.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/observability/__init__.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/observability/prometheus.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/py.typed +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense/version.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense_engine.egg-info/dependency_links.txt +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense_engine.egg-info/entry_points.txt +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/src/flowsense_engine.egg-info/top_level.txt +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_airflow_client_integration.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_airflow_factory.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_airflow_mapper.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_analysis_pipeline.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_analysis_request.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_analysis_use_case.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_analyzer.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_architecture.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_batch_analysis_output.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_change_point.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_cli_report.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_dag_summary.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_deprecations.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_history.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_impact.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_library_client.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_observability_assets.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_observation_validation.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_propagation.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_root_cause.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_timing.py +0 -0
- {flowsense_engine-0.4.0 → flowsense_engine-0.5.0}/tests/test_trend.py +0 -0
|
@@ -5,6 +5,58 @@ 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.0] - 2026-09-23
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- Added a production quickstart and executable bounded batch-analysis example.
|
|
19
|
+
- Added `flowsense doctor` for safe configuration, Airflow API, authentication,
|
|
20
|
+
and DAG-visibility diagnostics.
|
|
21
|
+
- Added `flowsense dags` for read-only DAG discovery with table and JSON output.
|
|
22
|
+
- Added `flowsense analyze-batch` for bounded multi-DAG CLI analysis with the
|
|
23
|
+
versioned batch JSON contract.
|
|
24
|
+
- Added severity-based CI exit thresholds to batch analysis.
|
|
25
|
+
- Added full analysis-policy configuration to the batch CLI.
|
|
26
|
+
- Added bounded DAG discovery to batch analysis with `--all-dags`,
|
|
27
|
+
`--dag-limit`, and optional paused-DAG inclusion.
|
|
28
|
+
- Added CLI access to the versioned batch output JSON Schema through
|
|
29
|
+
`flowsense schema --document batch`.
|
|
30
|
+
- Added reliable versioned JSON file output to single-DAG analysis through
|
|
31
|
+
`flowsense analyze --output-file`.
|
|
32
|
+
- Added reusable, versioned JSON analysis policies for single and batch CLI
|
|
33
|
+
commands, with explicit command-line overrides and JSON Schema export.
|
|
34
|
+
- Added versioned analysis-policy support to the optional Prometheus metrics
|
|
35
|
+
command and propagated the selected policy through every collection cycle.
|
|
36
|
+
- Added a validated per-cycle history limit to the Prometheus metrics command
|
|
37
|
+
so Airflow collection remains explicitly bounded.
|
|
38
|
+
- Added expanded Ruff quality rules, a 90% CI coverage gate, and graceful MCP
|
|
39
|
+
test skipping when the optional dependency is not installed.
|
|
40
|
+
- Reduced Airflow collection overhead with bounded server-side DAG run filters
|
|
41
|
+
and batched task-instance retrieval, including compatibility fallbacks for
|
|
42
|
+
deployments that do not support the optimized endpoints.
|
|
43
|
+
- Added explicit drift direction and effective MAD fields to analysis results,
|
|
44
|
+
plus configurable relative and absolute dispersion floors.
|
|
45
|
+
|
|
46
|
+
### Changed
|
|
47
|
+
|
|
48
|
+
- Airflow login tokens are now refreshed once after an unauthorized API
|
|
49
|
+
response, while static bearer, Basic, and custom authentication lifecycles
|
|
50
|
+
remain application-owned.
|
|
51
|
+
- Advanced the analysis output schema to version `1.2` for the new drift and
|
|
52
|
+
policy fields.
|
|
53
|
+
|
|
54
|
+
### Fixed
|
|
55
|
+
|
|
56
|
+
- Constant and near-constant baselines no longer classify negligible timing
|
|
57
|
+
noise as an automatic critical anomaly when raw MAD is zero or extremely
|
|
58
|
+
small.
|
|
59
|
+
|
|
8
60
|
## [0.4.0] - 2026-09-20
|
|
9
61
|
|
|
10
62
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flowsense-engine
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
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"
|
|
@@ -37,10 +38,12 @@ Dynamic: license-file
|
|
|
37
38
|
|
|
38
39
|
Temporal drift, anomaly detection, and dependency-aware propagation analysis for Apache Airflow.
|
|
39
40
|
|
|
40
|
-
Current package release: `0.
|
|
41
|
+
Current package release: `0.5.0`. See [CHANGELOG.md](CHANGELOG.md) for release
|
|
41
42
|
notes, [docs/architecture.md](docs/architecture.md) for the system architecture,
|
|
42
43
|
[docs/benchmarks.md](docs/benchmarks.md) for performance measurement, and
|
|
43
|
-
[docs/
|
|
44
|
+
[docs/production-quickstart.md](docs/production-quickstart.md) for a production
|
|
45
|
+
walkthrough. See [docs/migrating-to-0.5.md](docs/migrating-to-0.5.md) for the
|
|
46
|
+
current migration guidance.
|
|
44
47
|
Maintainers can use [docs/releasing.md](docs/releasing.md) as the release checklist.
|
|
45
48
|
|
|
46
49
|
FlowSense analyzes historical DAG executions to identify abnormal task behavior and trace how anomalies propagate through downstream dependencies.
|
|
@@ -153,6 +156,9 @@ Once published on PyPI, install the distribution with:
|
|
|
153
156
|
pip install flowsense-engine
|
|
154
157
|
```
|
|
155
158
|
|
|
159
|
+
For an end-to-end Airflow setup, follow the
|
|
160
|
+
[production quickstart](docs/production-quickstart.md).
|
|
161
|
+
|
|
156
162
|
The distribution name is `flowsense-engine`; Python imports and CLI commands
|
|
157
163
|
remain `flowsense`.
|
|
158
164
|
|
|
@@ -218,9 +224,15 @@ export $(grep -v '^#' .env | xargs)
|
|
|
218
224
|
Then run:
|
|
219
225
|
|
|
220
226
|
```bash
|
|
227
|
+
flowsense doctor
|
|
228
|
+
flowsense dags
|
|
221
229
|
flowsense analyze <dag_id>
|
|
230
|
+
flowsense analyze-batch <dag_id> [<dag_id> ...]
|
|
222
231
|
```
|
|
223
232
|
|
|
233
|
+
Both single and batch analysis commands support `--fail-on` for CI severity
|
|
234
|
+
gates.
|
|
235
|
+
|
|
224
236
|
The CLI report includes a DAG summary and separate tables for task drift,
|
|
225
237
|
handoff drift, change points, trends, propagation paths, and diagnostics.
|
|
226
238
|
Results are ordered by severity or subject so repeated analyses remain easy to
|
|
@@ -230,14 +242,30 @@ For automation and CI/CD integrations, request the versioned JSON document:
|
|
|
230
242
|
|
|
231
243
|
```bash
|
|
232
244
|
flowsense analyze <dag_id> --output json
|
|
245
|
+
flowsense analyze <dag_id> --output-file flowsense-analysis.json
|
|
233
246
|
```
|
|
234
247
|
|
|
248
|
+
`--output-file` always writes the versioned JSON contract and avoids relying on
|
|
249
|
+
shell redirection in CI jobs.
|
|
250
|
+
|
|
235
251
|
CI jobs can also fail when the analysis reaches a selected severity:
|
|
236
252
|
|
|
237
253
|
```bash
|
|
238
254
|
flowsense analyze <dag_id> --output json --fail-on high
|
|
239
255
|
```
|
|
240
256
|
|
|
257
|
+
Store reusable analysis settings in a versioned JSON policy file and share it
|
|
258
|
+
between single and batch analysis:
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
flowsense analyze <dag_id> --policy-file flowsense-policy.json
|
|
262
|
+
flowsense analyze-batch --all-dags --dag-limit 10 \
|
|
263
|
+
--policy-file flowsense-policy.json
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
Explicit policy options override values loaded from the file. Generate its JSON
|
|
267
|
+
Schema with `flowsense schema --document policy`.
|
|
268
|
+
|
|
241
269
|
`--fail-on` accepts `medium`, `high`, or `critical`. The report is always
|
|
242
270
|
written before FlowSense exits: code `0` means the severity is below the
|
|
243
271
|
threshold, code `2` means the threshold was reached, and code `1` remains
|
|
@@ -265,6 +293,8 @@ flowsense analyze <dag_id> --dag-run-id <dag_run_id>
|
|
|
265
293
|
|
|
266
294
|
The MCP tool exposes the same option as `dag_run_id`. Analysis output includes
|
|
267
295
|
`current_dag_run_id`; this field was introduced in output schema version `1.1`.
|
|
296
|
+
Output schema version `1.2` adds drift `direction`, the regularized
|
|
297
|
+
`effective_mad`, and the dispersion-floor policy values.
|
|
268
298
|
|
|
269
299
|
The JSON document and MCP tool response share the same serialization contract
|
|
270
300
|
and include a `schema_version` field. The serializer is also available from the
|
|
@@ -279,8 +309,13 @@ The same schema can be emitted without connecting to Airflow:
|
|
|
279
309
|
|
|
280
310
|
```bash
|
|
281
311
|
flowsense schema > flowsense-analysis.schema.json
|
|
312
|
+
flowsense schema --document batch > flowsense-batch.schema.json
|
|
282
313
|
```
|
|
283
314
|
|
|
315
|
+
The default remains the single-DAG analysis schema. Use `--document batch` to
|
|
316
|
+
emit the versioned batch envelope schema, including successful analyses and
|
|
317
|
+
per-DAG failure records.
|
|
318
|
+
|
|
284
319
|
This output is deterministic and can be used in CI contract checks, editor
|
|
285
320
|
tooling, or client code generation.
|
|
286
321
|
|
|
@@ -332,6 +367,8 @@ policy = AnalysisPolicy(
|
|
|
332
367
|
medium_threshold=2.5,
|
|
333
368
|
high_threshold=4.0,
|
|
334
369
|
critical_threshold=6.0,
|
|
370
|
+
minimum_relative_dispersion=0.01,
|
|
371
|
+
minimum_absolute_dispersion=0.001,
|
|
335
372
|
mapped_task_aggregation=MappedTaskAggregation.MAX,
|
|
336
373
|
change_point_minimum_segment_size=4,
|
|
337
374
|
change_point_score_threshold=4.0,
|
|
@@ -344,6 +381,8 @@ policy = AnalysisPolicy(
|
|
|
344
381
|
`baseline_window` limits the number of historical values used before the current
|
|
345
382
|
run. Mapped task durations can be aggregated with `MAX`, `MEAN`, or `SUM`. The
|
|
346
383
|
same policy options are available through the CLI and MCP tool.
|
|
384
|
+
The dispersion floors prevent constant or nearly constant baselines from
|
|
385
|
+
turning negligible timing noise into an automatic critical anomaly.
|
|
347
386
|
Change-point and trend detection can also be disabled independently with
|
|
348
387
|
`change_point_detection_enabled=False` or `trend_detection_enabled=False`.
|
|
349
388
|
|
|
@@ -383,7 +422,11 @@ information for a DAG.
|
|
|
383
422
|
Run continuous analysis and expose the latest DAG and bounded task-level metrics:
|
|
384
423
|
|
|
385
424
|
```bash
|
|
386
|
-
flowsense serve-metrics example_dag
|
|
425
|
+
flowsense serve-metrics example_dag \
|
|
426
|
+
--host 0.0.0.0 \
|
|
427
|
+
--port 9108 \
|
|
428
|
+
--history-run-limit 50 \
|
|
429
|
+
--policy-file flowsense-policy.json
|
|
387
430
|
```
|
|
388
431
|
|
|
389
432
|
See [docs/prometheus.md](docs/prometheus.md) for the metric contract,
|
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
Temporal drift, anomaly detection, and dependency-aware propagation analysis for Apache Airflow.
|
|
4
4
|
|
|
5
|
-
Current package release: `0.
|
|
5
|
+
Current package release: `0.5.0`. See [CHANGELOG.md](CHANGELOG.md) for release
|
|
6
6
|
notes, [docs/architecture.md](docs/architecture.md) for the system architecture,
|
|
7
7
|
[docs/benchmarks.md](docs/benchmarks.md) for performance measurement, and
|
|
8
|
-
[docs/
|
|
8
|
+
[docs/production-quickstart.md](docs/production-quickstart.md) for a production
|
|
9
|
+
walkthrough. See [docs/migrating-to-0.5.md](docs/migrating-to-0.5.md) for the
|
|
10
|
+
current migration guidance.
|
|
9
11
|
Maintainers can use [docs/releasing.md](docs/releasing.md) as the release checklist.
|
|
10
12
|
|
|
11
13
|
FlowSense analyzes historical DAG executions to identify abnormal task behavior and trace how anomalies propagate through downstream dependencies.
|
|
@@ -118,6 +120,9 @@ Once published on PyPI, install the distribution with:
|
|
|
118
120
|
pip install flowsense-engine
|
|
119
121
|
```
|
|
120
122
|
|
|
123
|
+
For an end-to-end Airflow setup, follow the
|
|
124
|
+
[production quickstart](docs/production-quickstart.md).
|
|
125
|
+
|
|
121
126
|
The distribution name is `flowsense-engine`; Python imports and CLI commands
|
|
122
127
|
remain `flowsense`.
|
|
123
128
|
|
|
@@ -183,9 +188,15 @@ export $(grep -v '^#' .env | xargs)
|
|
|
183
188
|
Then run:
|
|
184
189
|
|
|
185
190
|
```bash
|
|
191
|
+
flowsense doctor
|
|
192
|
+
flowsense dags
|
|
186
193
|
flowsense analyze <dag_id>
|
|
194
|
+
flowsense analyze-batch <dag_id> [<dag_id> ...]
|
|
187
195
|
```
|
|
188
196
|
|
|
197
|
+
Both single and batch analysis commands support `--fail-on` for CI severity
|
|
198
|
+
gates.
|
|
199
|
+
|
|
189
200
|
The CLI report includes a DAG summary and separate tables for task drift,
|
|
190
201
|
handoff drift, change points, trends, propagation paths, and diagnostics.
|
|
191
202
|
Results are ordered by severity or subject so repeated analyses remain easy to
|
|
@@ -195,14 +206,30 @@ For automation and CI/CD integrations, request the versioned JSON document:
|
|
|
195
206
|
|
|
196
207
|
```bash
|
|
197
208
|
flowsense analyze <dag_id> --output json
|
|
209
|
+
flowsense analyze <dag_id> --output-file flowsense-analysis.json
|
|
198
210
|
```
|
|
199
211
|
|
|
212
|
+
`--output-file` always writes the versioned JSON contract and avoids relying on
|
|
213
|
+
shell redirection in CI jobs.
|
|
214
|
+
|
|
200
215
|
CI jobs can also fail when the analysis reaches a selected severity:
|
|
201
216
|
|
|
202
217
|
```bash
|
|
203
218
|
flowsense analyze <dag_id> --output json --fail-on high
|
|
204
219
|
```
|
|
205
220
|
|
|
221
|
+
Store reusable analysis settings in a versioned JSON policy file and share it
|
|
222
|
+
between single and batch analysis:
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
flowsense analyze <dag_id> --policy-file flowsense-policy.json
|
|
226
|
+
flowsense analyze-batch --all-dags --dag-limit 10 \
|
|
227
|
+
--policy-file flowsense-policy.json
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
Explicit policy options override values loaded from the file. Generate its JSON
|
|
231
|
+
Schema with `flowsense schema --document policy`.
|
|
232
|
+
|
|
206
233
|
`--fail-on` accepts `medium`, `high`, or `critical`. The report is always
|
|
207
234
|
written before FlowSense exits: code `0` means the severity is below the
|
|
208
235
|
threshold, code `2` means the threshold was reached, and code `1` remains
|
|
@@ -230,6 +257,8 @@ flowsense analyze <dag_id> --dag-run-id <dag_run_id>
|
|
|
230
257
|
|
|
231
258
|
The MCP tool exposes the same option as `dag_run_id`. Analysis output includes
|
|
232
259
|
`current_dag_run_id`; this field was introduced in output schema version `1.1`.
|
|
260
|
+
Output schema version `1.2` adds drift `direction`, the regularized
|
|
261
|
+
`effective_mad`, and the dispersion-floor policy values.
|
|
233
262
|
|
|
234
263
|
The JSON document and MCP tool response share the same serialization contract
|
|
235
264
|
and include a `schema_version` field. The serializer is also available from the
|
|
@@ -244,8 +273,13 @@ The same schema can be emitted without connecting to Airflow:
|
|
|
244
273
|
|
|
245
274
|
```bash
|
|
246
275
|
flowsense schema > flowsense-analysis.schema.json
|
|
276
|
+
flowsense schema --document batch > flowsense-batch.schema.json
|
|
247
277
|
```
|
|
248
278
|
|
|
279
|
+
The default remains the single-DAG analysis schema. Use `--document batch` to
|
|
280
|
+
emit the versioned batch envelope schema, including successful analyses and
|
|
281
|
+
per-DAG failure records.
|
|
282
|
+
|
|
249
283
|
This output is deterministic and can be used in CI contract checks, editor
|
|
250
284
|
tooling, or client code generation.
|
|
251
285
|
|
|
@@ -297,6 +331,8 @@ policy = AnalysisPolicy(
|
|
|
297
331
|
medium_threshold=2.5,
|
|
298
332
|
high_threshold=4.0,
|
|
299
333
|
critical_threshold=6.0,
|
|
334
|
+
minimum_relative_dispersion=0.01,
|
|
335
|
+
minimum_absolute_dispersion=0.001,
|
|
300
336
|
mapped_task_aggregation=MappedTaskAggregation.MAX,
|
|
301
337
|
change_point_minimum_segment_size=4,
|
|
302
338
|
change_point_score_threshold=4.0,
|
|
@@ -309,6 +345,8 @@ policy = AnalysisPolicy(
|
|
|
309
345
|
`baseline_window` limits the number of historical values used before the current
|
|
310
346
|
run. Mapped task durations can be aggregated with `MAX`, `MEAN`, or `SUM`. The
|
|
311
347
|
same policy options are available through the CLI and MCP tool.
|
|
348
|
+
The dispersion floors prevent constant or nearly constant baselines from
|
|
349
|
+
turning negligible timing noise into an automatic critical anomaly.
|
|
312
350
|
Change-point and trend detection can also be disabled independently with
|
|
313
351
|
`change_point_detection_enabled=False` or `trend_detection_enabled=False`.
|
|
314
352
|
|
|
@@ -348,7 +386,11 @@ information for a DAG.
|
|
|
348
386
|
Run continuous analysis and expose the latest DAG and bounded task-level metrics:
|
|
349
387
|
|
|
350
388
|
```bash
|
|
351
|
-
flowsense serve-metrics example_dag
|
|
389
|
+
flowsense serve-metrics example_dag \
|
|
390
|
+
--host 0.0.0.0 \
|
|
391
|
+
--port 9108 \
|
|
392
|
+
--history-run-limit 50 \
|
|
393
|
+
--policy-file flowsense-policy.json
|
|
352
394
|
```
|
|
353
395
|
|
|
354
396
|
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.
|
|
@@ -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.
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
# Production quickstart
|
|
2
|
+
|
|
3
|
+
This guide runs FlowSense as an installed Python package against an existing
|
|
4
|
+
Apache Airflow deployment. FlowSense remains an in-process library and CLI; it
|
|
5
|
+
does not require a separate hosted service or database.
|
|
6
|
+
|
|
7
|
+
## 1. Install an isolated version
|
|
8
|
+
|
|
9
|
+
FlowSense requires Python 3.12 or 3.13.
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
python3.12 -m venv .venv
|
|
13
|
+
source .venv/bin/activate
|
|
14
|
+
python -m pip install "flowsense-engine==0.5.0"
|
|
15
|
+
flowsense --version
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
The expected version is `0.5.0`. Pin the version in production dependency files
|
|
19
|
+
and upgrade deliberately after reviewing the changelog.
|
|
20
|
+
|
|
21
|
+
## 2. Configure Airflow access
|
|
22
|
+
|
|
23
|
+
Keep credentials in a secret manager or injected environment variables rather
|
|
24
|
+
than source control.
|
|
25
|
+
|
|
26
|
+
For an Airflow 3 deployment using login-token exchange:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
export AIRFLOW_BASE_URL="https://airflow.example.com"
|
|
30
|
+
export AIRFLOW_API_VERSION="v2"
|
|
31
|
+
export AIRFLOW_AUTH_MODE="token"
|
|
32
|
+
export AIRFLOW_USERNAME="flowsense"
|
|
33
|
+
export AIRFLOW_PASSWORD="replace-from-secret-manager"
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
For an Airflow 2 deployment using Basic Auth:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
export AIRFLOW_BASE_URL="https://airflow.example.com"
|
|
40
|
+
export AIRFLOW_API_VERSION="v1"
|
|
41
|
+
export AIRFLOW_AUTH_MODE="basic"
|
|
42
|
+
export AIRFLOW_USERNAME="flowsense"
|
|
43
|
+
export AIRFLOW_PASSWORD="replace-from-secret-manager"
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Static bearer tokens use `AIRFLOW_AUTH_MODE=bearer` and
|
|
47
|
+
`AIRFLOW_BEARER_TOKEN`. Custom identity gateways can use the Python
|
|
48
|
+
authentication provider API described in [authentication.md](authentication.md).
|
|
49
|
+
|
|
50
|
+
Use a read-only Airflow identity with access to DAG definitions, DAG runs, and
|
|
51
|
+
task instances. Configure conservative network and history bounds:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
export AIRFLOW_CONNECT_TIMEOUT="10"
|
|
55
|
+
export AIRFLOW_READ_TIMEOUT="30"
|
|
56
|
+
export AIRFLOW_MAX_RETRIES="2"
|
|
57
|
+
export AIRFLOW_RETRY_BACKOFF="0.5"
|
|
58
|
+
export AIRFLOW_HISTORY_RUN_LIMIT="100"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## 3. Run a single-DAG smoke test
|
|
62
|
+
|
|
63
|
+
Validate configuration, authentication, API routing, and DAG visibility without
|
|
64
|
+
running an analysis:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
flowsense doctor
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
For automation, `flowsense doctor --output json` emits structured checks and
|
|
71
|
+
returns exit code `1` when a required check fails.
|
|
72
|
+
|
|
73
|
+
List the active DAGs visible to the configured identity:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
flowsense dags
|
|
77
|
+
flowsense dags --output json
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Paused DAGs are excluded unless `--include-paused` is provided.
|
|
81
|
+
|
|
82
|
+
Analyze an explicit, bounded DAG set directly from the CLI:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
flowsense analyze-batch orders payments inventory \
|
|
86
|
+
--history-run-limit 50 \
|
|
87
|
+
--max-concurrency 3 \
|
|
88
|
+
--fail-on high \
|
|
89
|
+
--output-file flowsense-batch.json
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
The command always writes the versioned batch JSON when analysis completes. It
|
|
93
|
+
returns exit code `1` if any DAG has an expected failure, while preserving all
|
|
94
|
+
successful results and failure records in the output file.
|
|
95
|
+
|
|
96
|
+
Batch analysis accepts the same policy controls as single-DAG analysis,
|
|
97
|
+
including history requirements, severity thresholds, mapped-task aggregation,
|
|
98
|
+
and change-point or trend detector settings.
|
|
99
|
+
|
|
100
|
+
For repeatable analysis across environments, create `flowsense-policy.json`:
|
|
101
|
+
|
|
102
|
+
```json
|
|
103
|
+
{
|
|
104
|
+
"schema_version": "1.0",
|
|
105
|
+
"minimum_history": 10,
|
|
106
|
+
"baseline_window": 30,
|
|
107
|
+
"medium_threshold": 2.0,
|
|
108
|
+
"high_threshold": 3.5,
|
|
109
|
+
"critical_threshold": 5.0,
|
|
110
|
+
"minimum_relative_dispersion": 0.01,
|
|
111
|
+
"minimum_absolute_dispersion": 0.001,
|
|
112
|
+
"mapped_task_aggregation": "MAX"
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Use the same file with either command:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
flowsense analyze orders --policy-file flowsense-policy.json
|
|
120
|
+
flowsense analyze-batch orders payments \
|
|
121
|
+
--policy-file flowsense-policy.json \
|
|
122
|
+
--minimum-history 15
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Explicit CLI policy options override file values. Unknown fields, unsupported
|
|
126
|
+
schema versions, malformed JSON, and invalid domain settings fail before an
|
|
127
|
+
Airflow analysis begins. Export the policy schema with
|
|
128
|
+
`flowsense schema --document policy`.
|
|
129
|
+
|
|
130
|
+
To discover active DAGs automatically, keep the workload explicitly bounded:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
flowsense analyze-batch \
|
|
134
|
+
--all-dags \
|
|
135
|
+
--dag-limit 10 \
|
|
136
|
+
--history-run-limit 50 \
|
|
137
|
+
--max-concurrency 3 \
|
|
138
|
+
--output-file flowsense-batch.json
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Discovery excludes paused DAGs by default. Add `--include-paused` only when
|
|
142
|
+
paused workflows are intentionally part of the analysis scope. Explicit DAG
|
|
143
|
+
ids and `--all-dags` are mutually exclusive.
|
|
144
|
+
|
|
145
|
+
With `--fail-on`, exit code `2` means at least one successful DAG analysis
|
|
146
|
+
reached the selected severity. Operational DAG failures take precedence and
|
|
147
|
+
retain exit code `1`.
|
|
148
|
+
|
|
149
|
+
Export the matching JSON Schema for validation in downstream automation:
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
flowsense schema --document batch > flowsense-batch.schema.json
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Start with a DAG that has several successful historical runs:
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
flowsense analyze example_dag --output json
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Exit code `0` means analysis completed. Exit code `1` represents a configuration,
|
|
162
|
+
Airflow, or analysis failure. When `--fail-on` is used, exit code `2` means the
|
|
163
|
+
selected severity threshold was reached.
|
|
164
|
+
|
|
165
|
+
For CI:
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
flowsense analyze example_dag \
|
|
169
|
+
--output-file analysis.json \
|
|
170
|
+
--fail-on high
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## 4. Discover and analyze several DAGs
|
|
174
|
+
|
|
175
|
+
The repository includes a bounded production example:
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
python examples/python/production_batch.py \
|
|
179
|
+
--dag-limit 10 \
|
|
180
|
+
--history-run-limit 50 \
|
|
181
|
+
--max-concurrency 3 \
|
|
182
|
+
--output flowsense-batch.json
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
The example:
|
|
186
|
+
|
|
187
|
+
1. loads validated Airflow configuration;
|
|
188
|
+
2. discovers active DAGs through the paginated Airflow API;
|
|
189
|
+
3. limits the number of selected DAGs;
|
|
190
|
+
4. runs independent analyses with bounded concurrency;
|
|
191
|
+
5. writes the versioned batch output contract.
|
|
192
|
+
|
|
193
|
+
Paused DAGs are excluded unless `--include-paused` is supplied. The command
|
|
194
|
+
returns exit code `1` when one or more expected DAG-level failures are present,
|
|
195
|
+
while still writing successful results and failure records.
|
|
196
|
+
|
|
197
|
+
## 5. Size the workload
|
|
198
|
+
|
|
199
|
+
Each DAG analysis reads DAG runs, task instances for the selected successful
|
|
200
|
+
runs, and the current DAG structure. Start with:
|
|
201
|
+
|
|
202
|
+
- `--dag-limit 5` or `10`;
|
|
203
|
+
- `--history-run-limit 30` to `100`;
|
|
204
|
+
- `--max-concurrency 1` to `3`.
|
|
205
|
+
|
|
206
|
+
Increase these values only after observing Airflow API latency and rate limits.
|
|
207
|
+
FlowSense retries transient `429`, `502`, `503`, and `504` responses, but
|
|
208
|
+
concurrency should remain below the capacity of the Airflow webserver.
|
|
209
|
+
|
|
210
|
+
## 6. Operate safely
|
|
211
|
+
|
|
212
|
+
- Pin the FlowSense package version.
|
|
213
|
+
- Inject secrets at runtime and never log them.
|
|
214
|
+
- Use a read-only Airflow account.
|
|
215
|
+
- Retain the output `schema_version` fields with stored JSON.
|
|
216
|
+
- Treat batch `failures` separately from anomaly severity.
|
|
217
|
+
- Alert when analysis stops succeeding, not only when severity increases.
|
|
218
|
+
- Validate upgrades in a staging Airflow environment.
|
|
219
|
+
|
|
220
|
+
Prometheus and Grafana are optional adapters. See [prometheus.md](prometheus.md),
|
|
221
|
+
[grafana.md](grafana.md), and [alerting.md](alerting.md) when metrics-based
|
|
222
|
+
operation is required.
|
|
223
|
+
|
|
224
|
+
## Troubleshooting
|
|
225
|
+
|
|
226
|
+
`401` or `403` responses usually indicate a mismatched authentication mode or
|
|
227
|
+
insufficient Airflow permissions. Confirm the API version and auth backend.
|
|
228
|
+
|
|
229
|
+
Insufficient-history diagnostics mean the DAG has fewer successful observations
|
|
230
|
+
than the active analysis policy requires. Increase the available history or
|
|
231
|
+
adjust the policy deliberately; do not treat missing history as a normal result.
|
|
232
|
+
|
|
233
|
+
For timeouts or rate limiting, lower batch concurrency and history limits before
|
|
234
|
+
increasing retry counts. See [authentication.md](authentication.md) and
|
|
235
|
+
[python-api.md](python-api.md) for deeper integration options.
|