detectkit 0.1.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.
Files changed (57) hide show
  1. detectkit-0.1.0/LICENSE +21 -0
  2. detectkit-0.1.0/MANIFEST.in +7 -0
  3. detectkit-0.1.0/PKG-INFO +231 -0
  4. detectkit-0.1.0/README.md +170 -0
  5. detectkit-0.1.0/detectkit/__init__.py +17 -0
  6. detectkit-0.1.0/detectkit/alerting/__init__.py +13 -0
  7. detectkit-0.1.0/detectkit/alerting/channels/__init__.py +21 -0
  8. detectkit-0.1.0/detectkit/alerting/channels/base.py +191 -0
  9. detectkit-0.1.0/detectkit/alerting/channels/email.py +146 -0
  10. detectkit-0.1.0/detectkit/alerting/channels/factory.py +193 -0
  11. detectkit-0.1.0/detectkit/alerting/channels/mattermost.py +53 -0
  12. detectkit-0.1.0/detectkit/alerting/channels/slack.py +55 -0
  13. detectkit-0.1.0/detectkit/alerting/channels/telegram.py +110 -0
  14. detectkit-0.1.0/detectkit/alerting/channels/webhook.py +139 -0
  15. detectkit-0.1.0/detectkit/alerting/orchestrator.py +368 -0
  16. detectkit-0.1.0/detectkit/cli/__init__.py +1 -0
  17. detectkit-0.1.0/detectkit/cli/commands/__init__.py +1 -0
  18. detectkit-0.1.0/detectkit/cli/commands/init.py +282 -0
  19. detectkit-0.1.0/detectkit/cli/commands/run.py +427 -0
  20. detectkit-0.1.0/detectkit/cli/commands/test_alert.py +184 -0
  21. detectkit-0.1.0/detectkit/cli/main.py +186 -0
  22. detectkit-0.1.0/detectkit/config/__init__.py +30 -0
  23. detectkit-0.1.0/detectkit/config/metric_config.py +467 -0
  24. detectkit-0.1.0/detectkit/config/profile.py +285 -0
  25. detectkit-0.1.0/detectkit/config/project_config.py +164 -0
  26. detectkit-0.1.0/detectkit/core/__init__.py +6 -0
  27. detectkit-0.1.0/detectkit/core/interval.py +132 -0
  28. detectkit-0.1.0/detectkit/core/models.py +106 -0
  29. detectkit-0.1.0/detectkit/database/__init__.py +27 -0
  30. detectkit-0.1.0/detectkit/database/clickhouse_manager.py +385 -0
  31. detectkit-0.1.0/detectkit/database/internal_tables.py +581 -0
  32. detectkit-0.1.0/detectkit/database/manager.py +324 -0
  33. detectkit-0.1.0/detectkit/database/tables.py +134 -0
  34. detectkit-0.1.0/detectkit/detectors/__init__.py +6 -0
  35. detectkit-0.1.0/detectkit/detectors/base.py +222 -0
  36. detectkit-0.1.0/detectkit/detectors/factory.py +138 -0
  37. detectkit-0.1.0/detectkit/detectors/statistical/__init__.py +8 -0
  38. detectkit-0.1.0/detectkit/detectors/statistical/iqr.py +230 -0
  39. detectkit-0.1.0/detectkit/detectors/statistical/mad.py +423 -0
  40. detectkit-0.1.0/detectkit/detectors/statistical/manual_bounds.py +177 -0
  41. detectkit-0.1.0/detectkit/detectors/statistical/zscore.py +225 -0
  42. detectkit-0.1.0/detectkit/loaders/__init__.py +6 -0
  43. detectkit-0.1.0/detectkit/loaders/metric_loader.py +470 -0
  44. detectkit-0.1.0/detectkit/loaders/query_template.py +164 -0
  45. detectkit-0.1.0/detectkit/orchestration/__init__.py +9 -0
  46. detectkit-0.1.0/detectkit/orchestration/task_manager.py +698 -0
  47. detectkit-0.1.0/detectkit/utils/__init__.py +1 -0
  48. detectkit-0.1.0/detectkit.egg-info/PKG-INFO +231 -0
  49. detectkit-0.1.0/detectkit.egg-info/SOURCES.txt +55 -0
  50. detectkit-0.1.0/detectkit.egg-info/dependency_links.txt +1 -0
  51. detectkit-0.1.0/detectkit.egg-info/entry_points.txt +2 -0
  52. detectkit-0.1.0/detectkit.egg-info/requires.txt +44 -0
  53. detectkit-0.1.0/detectkit.egg-info/top_level.txt +1 -0
  54. detectkit-0.1.0/pyproject.toml +149 -0
  55. detectkit-0.1.0/requirements.txt +8 -0
  56. detectkit-0.1.0/setup.cfg +4 -0
  57. detectkit-0.1.0/setup.py +6 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 detectkit team
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,7 @@
1
+ include README.md
2
+ include LICENSE
3
+ include requirements.txt
4
+ recursive-include detectkit *.py
5
+ recursive-exclude tests *
6
+ recursive-exclude * __pycache__
7
+ recursive-exclude * *.pyc
@@ -0,0 +1,231 @@
1
+ Metadata-Version: 2.4
2
+ Name: detectkit
3
+ Version: 0.1.0
4
+ Summary: Metric monitoring with automatic anomaly detection
5
+ Author: detectkit team
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/alexeiveselov92/detectkit
8
+ Project-URL: Documentation, https://github.com/alexeiveselov92/detectkit
9
+ Project-URL: Repository, https://github.com/alexeiveselov92/detectkit
10
+ Project-URL: Issues, https://github.com/alexeiveselov92/detectkit/issues
11
+ Keywords: monitoring,anomaly-detection,metrics,timeseries,alerting
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Topic :: Scientific/Engineering
21
+ Classifier: Topic :: System :: Monitoring
22
+ Requires-Python: >=3.10
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Requires-Dist: numpy>=1.24.0
26
+ Requires-Dist: pydantic>=2.0.0
27
+ Requires-Dist: pyyaml>=6.0
28
+ Requires-Dist: click>=8.0
29
+ Requires-Dist: jinja2>=3.0
30
+ Requires-Dist: orjson>=3.0
31
+ Provides-Extra: clickhouse
32
+ Requires-Dist: clickhouse-driver>=0.2.0; extra == "clickhouse"
33
+ Provides-Extra: postgres
34
+ Requires-Dist: psycopg2-binary>=2.9.0; extra == "postgres"
35
+ Provides-Extra: mysql
36
+ Requires-Dist: pymysql>=1.0.0; extra == "mysql"
37
+ Provides-Extra: all-db
38
+ Requires-Dist: clickhouse-driver>=0.2.0; extra == "all-db"
39
+ Requires-Dist: psycopg2-binary>=2.9.0; extra == "all-db"
40
+ Requires-Dist: pymysql>=1.0.0; extra == "all-db"
41
+ Provides-Extra: prophet
42
+ Requires-Dist: prophet>=1.1.0; extra == "prophet"
43
+ Provides-Extra: timesfm
44
+ Requires-Dist: timesfm>=0.1.0; extra == "timesfm"
45
+ Provides-Extra: advanced-detectors
46
+ Requires-Dist: prophet>=1.1.0; extra == "advanced-detectors"
47
+ Requires-Dist: timesfm>=0.1.0; extra == "advanced-detectors"
48
+ Provides-Extra: all
49
+ Requires-Dist: clickhouse-driver>=0.2.0; extra == "all"
50
+ Requires-Dist: psycopg2-binary>=2.9.0; extra == "all"
51
+ Requires-Dist: pymysql>=1.0.0; extra == "all"
52
+ Requires-Dist: prophet>=1.1.0; extra == "all"
53
+ Requires-Dist: timesfm>=0.1.0; extra == "all"
54
+ Provides-Extra: dev
55
+ Requires-Dist: pytest>=7.0; extra == "dev"
56
+ Requires-Dist: pytest-cov>=4.0; extra == "dev"
57
+ Requires-Dist: black>=23.0; extra == "dev"
58
+ Requires-Dist: mypy>=1.0; extra == "dev"
59
+ Requires-Dist: ruff>=0.1.0; extra == "dev"
60
+ Dynamic: license-file
61
+
62
+ # detectkit
63
+
64
+ **Metric monitoring with automatic anomaly detection**
65
+
66
+ `detectkit` is a Python library for data analysts and engineers to monitor time-series metrics with automatic anomaly detection and alerting.
67
+
68
+ ## Status
69
+
70
+ 🚧 **In Active Development** - Version 0.1.0
71
+
72
+ This is a complete rewrite of the original detectk library with modern architecture and best practices (2025).
73
+
74
+ ## Features
75
+
76
+ - ✅ **Pure numpy arrays** - No pandas dependency in core logic
77
+ - ✅ **Batch processing** - Efficient vectorized operations
78
+ - ✅ **Multiple detectors** - Statistical methods (Z-Score, MAD, IQR, Manual Bounds)
79
+ - ✅ **Alert channels** - Mattermost, Slack, Webhook support
80
+ - ✅ **Database agnostic** - ClickHouse, PostgreSQL, MySQL support
81
+ - ✅ **Idempotent operations** - Resume from interruptions
82
+ - 🚧 **CLI interface** - dbt-like commands (coming soon)
83
+
84
+ ## Installation
85
+
86
+ ```bash
87
+ pip install detectkit
88
+ ```
89
+
90
+ Or from source:
91
+
92
+ ```bash
93
+ git clone https://github.com/alexeiveselov92/detectkit
94
+ cd detectkit
95
+ pip install -e .
96
+ ```
97
+
98
+ ### Optional dependencies
99
+
100
+ ```bash
101
+ # ClickHouse support
102
+ pip install detectkit[clickhouse]
103
+
104
+ # All database drivers
105
+ pip install detectkit[all-db]
106
+
107
+ # Development dependencies
108
+ pip install detectkit[dev]
109
+ ```
110
+
111
+ ## Quick Start
112
+
113
+ ### CLI Usage (Recommended)
114
+
115
+ ```bash
116
+ # Create a new project
117
+ dtk init my_monitoring_project
118
+ cd my_monitoring_project
119
+
120
+ # Configure database in profiles.yml
121
+ # Then run your metrics
122
+ dtk run --select example_cpu_usage
123
+
124
+ # Run specific pipeline steps
125
+ dtk run --select cpu_usage --steps load,detect
126
+
127
+ # Run all critical metrics
128
+ dtk run --select tag:critical
129
+
130
+ # Reload data from specific date
131
+ dtk run --select cpu_usage --from 2024-01-01
132
+ ```
133
+
134
+ ### Python API Usage
135
+
136
+ ```python
137
+ import numpy as np
138
+ from detectkit.detectors.statistical import ZScoreDetector
139
+
140
+ # Your time-series data
141
+ timestamps = np.array([...], dtype='datetime64[ms]')
142
+ values = np.array([1.0, 2.0, 1.5, 10.0, 1.8]) # 10.0 is anomaly
143
+
144
+ # Create detector
145
+ detector = ZScoreDetector(threshold=3.0, window_size=100)
146
+
147
+ # Detect anomalies
148
+ data = {
149
+ 'timestamp': timestamps,
150
+ 'value': values
151
+ }
152
+ results = detector.detect(data)
153
+
154
+ # Check results
155
+ for result in results:
156
+ if result.is_anomaly:
157
+ print(f"Anomaly at {result.timestamp}: {result.value}")
158
+ ```
159
+
160
+ ## Architecture
161
+
162
+ - **Detectors** - Statistical and ML-based anomaly detection
163
+ - **Loaders** - Metric data loading from databases with gap filling
164
+ - **Alerting** - Multi-channel notifications with orchestration
165
+ - **Config** - YAML-based configuration (dbt-like)
166
+
167
+ ## Testing
168
+
169
+ ```bash
170
+ # Run tests
171
+ pytest tests/
172
+
173
+ # With coverage
174
+ pytest tests/ --cov=detectkit --cov-report=html
175
+ ```
176
+
177
+ **Current status:** 287 tests passing, 87% coverage
178
+
179
+ ## Development Status
180
+
181
+ ### ✅ Completed (Phases 1-6)
182
+ - ✅ **Phase 1**: Core models (Interval, TableModel, ColumnDefinition)
183
+ - ✅ **Phase 2**: Database managers & data loading (MetricLoader, gap filling, seasonality)
184
+ - ✅ **Phase 3**: Statistical detectors (Z-Score, MAD, IQR, Manual Bounds)
185
+ - ✅ **Phase 4**: Alerting system (Channels, Orchestrator, consecutive anomalies)
186
+ - ✅ **Phase 5**: Task manager (Pipeline execution, locking, idempotency)
187
+ - ✅ **Phase 6**: CLI commands (dtk init, dtk run with selectors)
188
+
189
+ ### 🔄 Integration Status
190
+ - ⚠️ Full end-to-end integration pending (database connection required)
191
+ - ⚠️ Advanced detectors (Prophet, TimesFM) - optional extras
192
+ - ⚠️ Additional alert channels (Telegram, Email) - optional
193
+
194
+ See [TODO.md](TODO.md) for detailed development roadmap.
195
+
196
+ ## Documentation
197
+
198
+ - [ARCHITECTURE.md](ARCHITECTURE.md) - System architecture and design
199
+ - [TECHNICAL_SPEC.md](TECHNICAL_SPEC.md) - Complete technical specification (Russian)
200
+ - [TODO.md](TODO.md) - Development roadmap
201
+ - [CLAUDE.md](CLAUDE.md) - Development context for AI assistants
202
+
203
+ ## Requirements
204
+
205
+ - Python 3.10+
206
+ - numpy >= 1.24.0
207
+ - pydantic >= 2.0.0
208
+ - click >= 8.0
209
+ - PyYAML >= 6.0
210
+ - Jinja2 >= 3.0
211
+
212
+ ## License
213
+
214
+ MIT License - See LICENSE file for details
215
+
216
+ ## Contributing
217
+
218
+ This project is currently in active development. Contributions are welcome once we reach v1.0.0.
219
+
220
+ ## Changelog
221
+
222
+ ### 0.1.0 (2025-11-07)
223
+ - Initial release with complete rewrite
224
+ - ✅ Core foundation: models, database, config
225
+ - ✅ Metric loading with gap filling and seasonality extraction
226
+ - ✅ Statistical detectors (Z-Score, MAD, IQR, Manual Bounds)
227
+ - ✅ Alert channels (Webhook, Mattermost, Slack)
228
+ - ✅ Alert orchestration with consecutive anomaly logic
229
+ - ✅ Task manager for pipeline execution
230
+ - ✅ CLI commands (dtk init, dtk run)
231
+ - 📊 287 unit tests, 87% coverage
@@ -0,0 +1,170 @@
1
+ # detectkit
2
+
3
+ **Metric monitoring with automatic anomaly detection**
4
+
5
+ `detectkit` is a Python library for data analysts and engineers to monitor time-series metrics with automatic anomaly detection and alerting.
6
+
7
+ ## Status
8
+
9
+ 🚧 **In Active Development** - Version 0.1.0
10
+
11
+ This is a complete rewrite of the original detectk library with modern architecture and best practices (2025).
12
+
13
+ ## Features
14
+
15
+ - ✅ **Pure numpy arrays** - No pandas dependency in core logic
16
+ - ✅ **Batch processing** - Efficient vectorized operations
17
+ - ✅ **Multiple detectors** - Statistical methods (Z-Score, MAD, IQR, Manual Bounds)
18
+ - ✅ **Alert channels** - Mattermost, Slack, Webhook support
19
+ - ✅ **Database agnostic** - ClickHouse, PostgreSQL, MySQL support
20
+ - ✅ **Idempotent operations** - Resume from interruptions
21
+ - 🚧 **CLI interface** - dbt-like commands (coming soon)
22
+
23
+ ## Installation
24
+
25
+ ```bash
26
+ pip install detectkit
27
+ ```
28
+
29
+ Or from source:
30
+
31
+ ```bash
32
+ git clone https://github.com/alexeiveselov92/detectkit
33
+ cd detectkit
34
+ pip install -e .
35
+ ```
36
+
37
+ ### Optional dependencies
38
+
39
+ ```bash
40
+ # ClickHouse support
41
+ pip install detectkit[clickhouse]
42
+
43
+ # All database drivers
44
+ pip install detectkit[all-db]
45
+
46
+ # Development dependencies
47
+ pip install detectkit[dev]
48
+ ```
49
+
50
+ ## Quick Start
51
+
52
+ ### CLI Usage (Recommended)
53
+
54
+ ```bash
55
+ # Create a new project
56
+ dtk init my_monitoring_project
57
+ cd my_monitoring_project
58
+
59
+ # Configure database in profiles.yml
60
+ # Then run your metrics
61
+ dtk run --select example_cpu_usage
62
+
63
+ # Run specific pipeline steps
64
+ dtk run --select cpu_usage --steps load,detect
65
+
66
+ # Run all critical metrics
67
+ dtk run --select tag:critical
68
+
69
+ # Reload data from specific date
70
+ dtk run --select cpu_usage --from 2024-01-01
71
+ ```
72
+
73
+ ### Python API Usage
74
+
75
+ ```python
76
+ import numpy as np
77
+ from detectkit.detectors.statistical import ZScoreDetector
78
+
79
+ # Your time-series data
80
+ timestamps = np.array([...], dtype='datetime64[ms]')
81
+ values = np.array([1.0, 2.0, 1.5, 10.0, 1.8]) # 10.0 is anomaly
82
+
83
+ # Create detector
84
+ detector = ZScoreDetector(threshold=3.0, window_size=100)
85
+
86
+ # Detect anomalies
87
+ data = {
88
+ 'timestamp': timestamps,
89
+ 'value': values
90
+ }
91
+ results = detector.detect(data)
92
+
93
+ # Check results
94
+ for result in results:
95
+ if result.is_anomaly:
96
+ print(f"Anomaly at {result.timestamp}: {result.value}")
97
+ ```
98
+
99
+ ## Architecture
100
+
101
+ - **Detectors** - Statistical and ML-based anomaly detection
102
+ - **Loaders** - Metric data loading from databases with gap filling
103
+ - **Alerting** - Multi-channel notifications with orchestration
104
+ - **Config** - YAML-based configuration (dbt-like)
105
+
106
+ ## Testing
107
+
108
+ ```bash
109
+ # Run tests
110
+ pytest tests/
111
+
112
+ # With coverage
113
+ pytest tests/ --cov=detectkit --cov-report=html
114
+ ```
115
+
116
+ **Current status:** 287 tests passing, 87% coverage
117
+
118
+ ## Development Status
119
+
120
+ ### ✅ Completed (Phases 1-6)
121
+ - ✅ **Phase 1**: Core models (Interval, TableModel, ColumnDefinition)
122
+ - ✅ **Phase 2**: Database managers & data loading (MetricLoader, gap filling, seasonality)
123
+ - ✅ **Phase 3**: Statistical detectors (Z-Score, MAD, IQR, Manual Bounds)
124
+ - ✅ **Phase 4**: Alerting system (Channels, Orchestrator, consecutive anomalies)
125
+ - ✅ **Phase 5**: Task manager (Pipeline execution, locking, idempotency)
126
+ - ✅ **Phase 6**: CLI commands (dtk init, dtk run with selectors)
127
+
128
+ ### 🔄 Integration Status
129
+ - ⚠️ Full end-to-end integration pending (database connection required)
130
+ - ⚠️ Advanced detectors (Prophet, TimesFM) - optional extras
131
+ - ⚠️ Additional alert channels (Telegram, Email) - optional
132
+
133
+ See [TODO.md](TODO.md) for detailed development roadmap.
134
+
135
+ ## Documentation
136
+
137
+ - [ARCHITECTURE.md](ARCHITECTURE.md) - System architecture and design
138
+ - [TECHNICAL_SPEC.md](TECHNICAL_SPEC.md) - Complete technical specification (Russian)
139
+ - [TODO.md](TODO.md) - Development roadmap
140
+ - [CLAUDE.md](CLAUDE.md) - Development context for AI assistants
141
+
142
+ ## Requirements
143
+
144
+ - Python 3.10+
145
+ - numpy >= 1.24.0
146
+ - pydantic >= 2.0.0
147
+ - click >= 8.0
148
+ - PyYAML >= 6.0
149
+ - Jinja2 >= 3.0
150
+
151
+ ## License
152
+
153
+ MIT License - See LICENSE file for details
154
+
155
+ ## Contributing
156
+
157
+ This project is currently in active development. Contributions are welcome once we reach v1.0.0.
158
+
159
+ ## Changelog
160
+
161
+ ### 0.1.0 (2025-11-07)
162
+ - Initial release with complete rewrite
163
+ - ✅ Core foundation: models, database, config
164
+ - ✅ Metric loading with gap filling and seasonality extraction
165
+ - ✅ Statistical detectors (Z-Score, MAD, IQR, Manual Bounds)
166
+ - ✅ Alert channels (Webhook, Mattermost, Slack)
167
+ - ✅ Alert orchestration with consecutive anomaly logic
168
+ - ✅ Task manager for pipeline execution
169
+ - ✅ CLI commands (dtk init, dtk run)
170
+ - 📊 287 unit tests, 87% coverage
@@ -0,0 +1,17 @@
1
+ """
2
+ detectk - Anomaly Detection for Time-Series Metrics
3
+
4
+ A Python library for data analysts and engineers to monitor metrics with automatic anomaly detection.
5
+ """
6
+
7
+ __version__ = "0.1.0"
8
+
9
+ from detectkit.core.interval import Interval
10
+ from detectkit.core.models import ColumnDefinition, TableModel
11
+
12
+ __all__ = [
13
+ "Interval",
14
+ "ColumnDefinition",
15
+ "TableModel",
16
+ "__version__",
17
+ ]
@@ -0,0 +1,13 @@
1
+ """Alerting functionality for detectk."""
2
+
3
+ from detectkit.alerting.orchestrator import (
4
+ AlertConditions,
5
+ AlertOrchestrator,
6
+ DetectionRecord,
7
+ )
8
+
9
+ __all__ = [
10
+ "AlertOrchestrator",
11
+ "AlertConditions",
12
+ "DetectionRecord",
13
+ ]
@@ -0,0 +1,21 @@
1
+ """Alert channels for external notifications."""
2
+
3
+ from detectkit.alerting.channels.base import AlertData, BaseAlertChannel
4
+ from detectkit.alerting.channels.mattermost import MattermostChannel
5
+ from detectkit.alerting.channels.slack import SlackChannel
6
+ from detectkit.alerting.channels.webhook import WebhookChannel
7
+ from detectkit.alerting.channels.telegram import TelegramChannel
8
+ from detectkit.alerting.channels.email import EmailChannel
9
+
10
+ from detectkit.alerting.channels.factory import AlertChannelFactory
11
+
12
+ __all__ = [
13
+ "AlertData",
14
+ "BaseAlertChannel",
15
+ "WebhookChannel",
16
+ "MattermostChannel",
17
+ "SlackChannel",
18
+ "TelegramChannel",
19
+ "EmailChannel",
20
+ "AlertChannelFactory",
21
+ ]
@@ -0,0 +1,191 @@
1
+ """
2
+ Base alert channel interface.
3
+
4
+ All alert channels must inherit from BaseAlertChannel and implement
5
+ the send() method for delivering alerts to specific destinations.
6
+ """
7
+
8
+ from abc import ABC, abstractmethod
9
+ from dataclasses import dataclass
10
+ from typing import Any, Dict, List, Optional
11
+
12
+ from detectkit.detectors.base import DetectionResult
13
+
14
+
15
+ @dataclass
16
+ class AlertData:
17
+ """
18
+ Data for alert message.
19
+
20
+ Contains all information needed to format and send an alert.
21
+
22
+ Attributes:
23
+ metric_name: Name of the metric
24
+ timestamp: Timestamp of the anomaly (datetime64)
25
+ timezone: Timezone for display (e.g., "Europe/Moscow")
26
+ value: Actual metric value
27
+ confidence_lower: Lower confidence bound
28
+ confidence_upper: Upper confidence bound
29
+ detector_name: Name/ID of detector that found the anomaly
30
+ detector_params: Detector parameters (JSON string)
31
+ direction: Direction of anomaly ("above" or "below")
32
+ severity: Severity score
33
+ detection_metadata: Additional metadata from detector
34
+ consecutive_count: Number of consecutive anomalies
35
+ """
36
+
37
+ metric_name: str
38
+ timestamp: Any # datetime64 or datetime
39
+ timezone: str
40
+ value: float
41
+ confidence_lower: Optional[float]
42
+ confidence_upper: Optional[float]
43
+ detector_name: str
44
+ detector_params: str
45
+ direction: str
46
+ severity: float
47
+ detection_metadata: Dict[str, Any]
48
+ consecutive_count: int = 1
49
+
50
+
51
+ class BaseAlertChannel(ABC):
52
+ """
53
+ Abstract base class for alert channels.
54
+
55
+ Alert channels deliver notifications to external systems when
56
+ anomalies are detected. Each channel implements a specific
57
+ delivery mechanism (webhook, email, etc.).
58
+
59
+ Example:
60
+ >>> class MyChannel(BaseAlertChannel):
61
+ ... def send(self, alert_data, template=None):
62
+ ... message = self.format_message(alert_data, template)
63
+ ... # Send via specific mechanism
64
+ ... return True
65
+ """
66
+
67
+ @abstractmethod
68
+ def send(
69
+ self,
70
+ alert_data: AlertData,
71
+ template: Optional[str] = None,
72
+ ) -> bool:
73
+ """
74
+ Send alert to this channel.
75
+
76
+ Args:
77
+ alert_data: Alert data to send
78
+ template: Optional custom message template
79
+ Uses default template if None
80
+
81
+ Returns:
82
+ True if sent successfully, False otherwise
83
+
84
+ Raises:
85
+ Exception: If sending fails critically
86
+
87
+ Example:
88
+ >>> alert = AlertData(
89
+ ... metric_name="cpu_usage",
90
+ ... timestamp=datetime.now(),
91
+ ... value=95.0,
92
+ ... ...
93
+ ... )
94
+ >>> success = channel.send(alert)
95
+ """
96
+ pass
97
+
98
+ def format_message(
99
+ self,
100
+ alert_data: AlertData,
101
+ template: Optional[str] = None,
102
+ ) -> str:
103
+ """
104
+ Format alert message from template.
105
+
106
+ Uses default template if none provided. Template variables:
107
+ - {metric_name}
108
+ - {timestamp}
109
+ - {timezone}
110
+ - {value}
111
+ - {confidence_lower}
112
+ - {confidence_upper}
113
+ - {detector_name}
114
+ - {direction}
115
+ - {severity}
116
+ - {consecutive_count}
117
+
118
+ Args:
119
+ alert_data: Alert data to format
120
+ template: Optional custom template string
121
+
122
+ Returns:
123
+ Formatted message string
124
+
125
+ Example:
126
+ >>> template = "Anomaly in {metric_name}: {value}"
127
+ >>> message = channel.format_message(alert_data, template)
128
+ """
129
+ if template is None:
130
+ template = self.get_default_template()
131
+
132
+ # Format timestamp to string
133
+ from datetime import datetime
134
+ import numpy as np
135
+
136
+ ts = alert_data.timestamp
137
+ if isinstance(ts, np.datetime64):
138
+ ts = ts.astype(datetime)
139
+
140
+ # Format timestamp with timezone
141
+ ts_str = ts.strftime("%Y-%m-%d %H:%M:%S")
142
+ if alert_data.timezone:
143
+ ts_str = f"{ts_str} ({alert_data.timezone})"
144
+
145
+ # Format confidence interval
146
+ if alert_data.confidence_lower is not None and alert_data.confidence_upper is not None:
147
+ confidence_str = f"[{alert_data.confidence_lower:.2f}, {alert_data.confidence_upper:.2f}]"
148
+ else:
149
+ confidence_str = "N/A"
150
+
151
+ # Format message
152
+ try:
153
+ message = template.format(
154
+ metric_name=alert_data.metric_name,
155
+ timestamp=ts_str,
156
+ timezone=alert_data.timezone,
157
+ value=alert_data.value,
158
+ confidence_lower=alert_data.confidence_lower,
159
+ confidence_upper=alert_data.confidence_upper,
160
+ confidence_interval=confidence_str,
161
+ detector_name=alert_data.detector_name,
162
+ direction=alert_data.direction,
163
+ severity=alert_data.severity,
164
+ consecutive_count=alert_data.consecutive_count,
165
+ )
166
+ except KeyError as e:
167
+ # If template has unknown variables, fall back to default
168
+ message = self.format_message(alert_data, self.get_default_template())
169
+
170
+ return message
171
+
172
+ def get_default_template(self) -> str:
173
+ """
174
+ Get default message template.
175
+
176
+ Returns:
177
+ Default template string
178
+ """
179
+ return (
180
+ "Anomaly detected in metric: {metric_name}\n"
181
+ "Time: {timestamp}\n"
182
+ "Value: {value}\n"
183
+ "Confidence interval: {confidence_interval}\n"
184
+ "Detector: {detector_name}\n"
185
+ "Direction: {direction}\n"
186
+ "Severity: {severity:.2f}"
187
+ )
188
+
189
+ def __repr__(self) -> str:
190
+ """String representation of channel."""
191
+ return f"{self.__class__.__name__}()"