A Python-based notification system that monitors ETL processes and sends alerts through various channels (currently supporting Microsoft Teams).
The ETL Notifier is designed to:
- Monitor ETL executions through database queries
- Cache results to prevent duplicate notifications
- Send formatted notifications through configurable channels
- Support multiple data sources and notification methods
etl_notifier/
├── src/
│ └── etl_notifier/
│ ├── models/ # Data models
│ ├── services/
│ │ ├── cache/ # Cache implementations
│ │ ├── data_source/ # Data source implementations
│ │ └── notification/ # Notification strategies
│ └── main.py # Application entry point
├── config/
│ └── queries.yml # Query and notification configuration
├── tests/ # Test suite
├── scripts/ # Utility scripts
├── .env.example # Example environment configuration
└── README.md # This file
- Python 3.8 or higher
- ODBC Driver 17 for SQL Server
- Access to the target database
- Microsoft Teams webhook URL (or other supported notification platform)
- Clone the repository:
git clone [repository-url]
cd etl-notifier- Create and activate a virtual environment:
python -m venv venv
source venv/bin/activate # On Windows: .\venv\Scripts\activate- Install dependencies:
pip install -e ".[dev]"- Set up environment configuration:
./scripts/setup_env.sh- Edit the
.envfile with your configuration values:
ETL_DB_CONNECTION_STRING="Driver={ODBC Driver 17 for SQL Server};Server=your-server;Database=your-db;Authentication=ActiveDirectoryInteractive;UID=your-username;"
ETL_TEAMS_WEBHOOK_URL="your-teams-webhook-url"The application uses two main configuration files:
-
.env- Environment variables:- Database connection string
- Webhook URLs
- Cache settings
- Application settings
-
config/queries.yml- Application configuration:
notification:
type: teams
webhook_url: ${ETL_TEAMS_WEBHOOK_URL}
sources:
database:
type: database
connection_string: ${ETL_DB_CONNECTION_STRING}
queries:
database_failures:
source: database
query:
sql: "YOUR_QUERY_HERE"
message_single: "Template for single failure"
message_multiple: "Template for multiple failures"- Create a new class in
services/data_source/implementing theDataSourceinterface:
from .base import DataSource
class NewDataSource(DataSource):
def execute_query(self, query: Dict[str, Any]) -> List[Dict[str, Any]]:
# Implementation here
pass- Add the new source type to
ETLNotifier.SOURCE_TYPES
- Create a new class in
services/notification/implementing theNotificationStrategyinterface:
from .strategy import NotificationStrategy
class NewNotificationStrategy(NotificationStrategy):
def send_notification(self, message: str) -> None:
# Implementation here
pass- Add the new strategy type to
ETLNotifier.SOURCE_TYPES
pytest tests/The project uses:
- Black for code formatting
- isort for import sorting
- mypy for type checking
- flake8 for linting
Run all checks:
black src/ tests/
isort src/ tests/
mypy src/
flake8 src/ tests/The project follows SOLID principles and uses several design patterns:
-
Strategy Pattern:
- For notification implementations
- For data source implementations
- For cache implementations
-
Dependency Injection:
- Components receive their dependencies through constructor injection
- Makes testing and extending functionality easier
-
Abstract Base Classes:
- Define clear interfaces for implementations
- Ensure consistency across different implementations
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request