fix: Fix ImportError in alert_processor alerts.py by using DatabaseManager pattern
The alert_processor service was crashing with: ImportError: cannot import name 'get_db' from 'shared.database.base' Root cause: alerts.py was using Depends(get_db) pattern which doesn't exist in shared.database.base. Fix: Refactored alerts.py to follow the same pattern as analytics.py: - Removed Depends(get_db) dependency injection - Each endpoint now creates a DatabaseManager instance - Uses db_manager.get_session() context manager for database access This matches the alert_processor service's existing architecture in analytics.py.
This commit is contained in:
@@ -3,15 +3,13 @@
|
|||||||
Alerts API endpoints for dashboard and alert management
|
Alerts API endpoints for dashboard and alert management
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from fastapi import APIRouter, Depends, HTTPException, Query, Path
|
from fastapi import APIRouter, HTTPException, Query, Path
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
|
||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel, Field
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import structlog
|
import structlog
|
||||||
|
|
||||||
from shared.database.base import get_db
|
|
||||||
from app.repositories.alerts_repository import AlertsRepository
|
from app.repositories.alerts_repository import AlertsRepository
|
||||||
from app.models.alerts import AlertSeverity, AlertStatus
|
from app.models.alerts import AlertSeverity, AlertStatus
|
||||||
|
|
||||||
@@ -76,8 +74,7 @@ class AlertsListResponse(BaseModel):
|
|||||||
description="Get summary of alerts by severity and status for dashboard health indicator"
|
description="Get summary of alerts by severity and status for dashboard health indicator"
|
||||||
)
|
)
|
||||||
async def get_alerts_summary(
|
async def get_alerts_summary(
|
||||||
tenant_id: UUID = Path(..., description="Tenant ID"),
|
tenant_id: UUID = Path(..., description="Tenant ID")
|
||||||
db: AsyncSession = Depends(get_db)
|
|
||||||
) -> AlertsSummaryResponse:
|
) -> AlertsSummaryResponse:
|
||||||
"""
|
"""
|
||||||
Get alerts summary for dashboard
|
Get alerts summary for dashboard
|
||||||
@@ -85,10 +82,17 @@ async def get_alerts_summary(
|
|||||||
Returns counts of alerts grouped by severity and status.
|
Returns counts of alerts grouped by severity and status.
|
||||||
Critical count maps to URGENT severity for dashboard compatibility.
|
Critical count maps to URGENT severity for dashboard compatibility.
|
||||||
"""
|
"""
|
||||||
|
from app.config import AlertProcessorConfig
|
||||||
|
from shared.database.base import create_database_manager
|
||||||
|
|
||||||
try:
|
try:
|
||||||
repo = AlertsRepository(db)
|
config = AlertProcessorConfig()
|
||||||
summary = await repo.get_alerts_summary(tenant_id)
|
db_manager = create_database_manager(config.DATABASE_URL, "alert-processor")
|
||||||
return AlertsSummaryResponse(**summary)
|
|
||||||
|
async with db_manager.get_session() as session:
|
||||||
|
repo = AlertsRepository(session)
|
||||||
|
summary = await repo.get_alerts_summary(tenant_id)
|
||||||
|
return AlertsSummaryResponse(**summary)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error("Error getting alerts summary", error=str(e), tenant_id=str(tenant_id))
|
logger.error("Error getting alerts summary", error=str(e), tenant_id=str(tenant_id))
|
||||||
@@ -107,8 +111,7 @@ async def get_alerts(
|
|||||||
status: Optional[str] = Query(None, description="Filter by status: active, resolved, acknowledged, ignored"),
|
status: Optional[str] = Query(None, description="Filter by status: active, resolved, acknowledged, ignored"),
|
||||||
resolved: Optional[bool] = Query(None, description="Filter by resolved status: true=resolved only, false=unresolved only"),
|
resolved: Optional[bool] = Query(None, description="Filter by resolved status: true=resolved only, false=unresolved only"),
|
||||||
limit: int = Query(100, ge=1, le=1000, description="Maximum number of results"),
|
limit: int = Query(100, ge=1, le=1000, description="Maximum number of results"),
|
||||||
offset: int = Query(0, ge=0, description="Pagination offset"),
|
offset: int = Query(0, ge=0, description="Pagination offset")
|
||||||
db: AsyncSession = Depends(get_db)
|
|
||||||
) -> AlertsListResponse:
|
) -> AlertsListResponse:
|
||||||
"""
|
"""
|
||||||
Get filtered list of alerts
|
Get filtered list of alerts
|
||||||
@@ -119,6 +122,9 @@ async def get_alerts(
|
|||||||
- resolved: boolean filter for resolved status
|
- resolved: boolean filter for resolved status
|
||||||
- pagination: limit and offset
|
- pagination: limit and offset
|
||||||
"""
|
"""
|
||||||
|
from app.config import AlertProcessorConfig
|
||||||
|
from shared.database.base import create_database_manager
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Validate severity enum
|
# Validate severity enum
|
||||||
if severity and severity not in [s.value for s in AlertSeverity]:
|
if severity and severity not in [s.value for s in AlertSeverity]:
|
||||||
@@ -134,43 +140,47 @@ async def get_alerts(
|
|||||||
detail=f"Invalid status. Must be one of: {[s.value for s in AlertStatus]}"
|
detail=f"Invalid status. Must be one of: {[s.value for s in AlertStatus]}"
|
||||||
)
|
)
|
||||||
|
|
||||||
repo = AlertsRepository(db)
|
config = AlertProcessorConfig()
|
||||||
alerts = await repo.get_alerts(
|
db_manager = create_database_manager(config.DATABASE_URL, "alert-processor")
|
||||||
tenant_id=tenant_id,
|
|
||||||
severity=severity,
|
|
||||||
status=status,
|
|
||||||
resolved=resolved,
|
|
||||||
limit=limit,
|
|
||||||
offset=offset
|
|
||||||
)
|
|
||||||
|
|
||||||
# Convert to response models
|
async with db_manager.get_session() as session:
|
||||||
alert_responses = [
|
repo = AlertsRepository(session)
|
||||||
AlertResponse(
|
alerts = await repo.get_alerts(
|
||||||
id=str(alert.id),
|
tenant_id=tenant_id,
|
||||||
tenant_id=str(alert.tenant_id),
|
severity=severity,
|
||||||
item_type=alert.item_type,
|
status=status,
|
||||||
alert_type=alert.alert_type,
|
resolved=resolved,
|
||||||
severity=alert.severity,
|
limit=limit,
|
||||||
status=alert.status,
|
offset=offset
|
||||||
service=alert.service,
|
|
||||||
title=alert.title,
|
|
||||||
message=alert.message,
|
|
||||||
actions=alert.actions,
|
|
||||||
alert_metadata=alert.alert_metadata,
|
|
||||||
created_at=alert.created_at,
|
|
||||||
updated_at=alert.updated_at,
|
|
||||||
resolved_at=alert.resolved_at
|
|
||||||
)
|
)
|
||||||
for alert in alerts
|
|
||||||
]
|
|
||||||
|
|
||||||
return AlertsListResponse(
|
# Convert to response models
|
||||||
alerts=alert_responses,
|
alert_responses = [
|
||||||
total=len(alert_responses), # In a real implementation, you'd query the total count separately
|
AlertResponse(
|
||||||
limit=limit,
|
id=str(alert.id),
|
||||||
offset=offset
|
tenant_id=str(alert.tenant_id),
|
||||||
)
|
item_type=alert.item_type,
|
||||||
|
alert_type=alert.alert_type,
|
||||||
|
severity=alert.severity,
|
||||||
|
status=alert.status,
|
||||||
|
service=alert.service,
|
||||||
|
title=alert.title,
|
||||||
|
message=alert.message,
|
||||||
|
actions=alert.actions,
|
||||||
|
alert_metadata=alert.alert_metadata,
|
||||||
|
created_at=alert.created_at,
|
||||||
|
updated_at=alert.updated_at,
|
||||||
|
resolved_at=alert.resolved_at
|
||||||
|
)
|
||||||
|
for alert in alerts
|
||||||
|
]
|
||||||
|
|
||||||
|
return AlertsListResponse(
|
||||||
|
alerts=alert_responses,
|
||||||
|
total=len(alert_responses), # In a real implementation, you'd query the total count separately
|
||||||
|
limit=limit,
|
||||||
|
offset=offset
|
||||||
|
)
|
||||||
|
|
||||||
except HTTPException:
|
except HTTPException:
|
||||||
raise
|
raise
|
||||||
@@ -187,33 +197,39 @@ async def get_alerts(
|
|||||||
)
|
)
|
||||||
async def get_alert(
|
async def get_alert(
|
||||||
tenant_id: UUID = Path(..., description="Tenant ID"),
|
tenant_id: UUID = Path(..., description="Tenant ID"),
|
||||||
alert_id: UUID = Path(..., description="Alert ID"),
|
alert_id: UUID = Path(..., description="Alert ID")
|
||||||
db: AsyncSession = Depends(get_db)
|
|
||||||
) -> AlertResponse:
|
) -> AlertResponse:
|
||||||
"""Get a specific alert by ID"""
|
"""Get a specific alert by ID"""
|
||||||
|
from app.config import AlertProcessorConfig
|
||||||
|
from shared.database.base import create_database_manager
|
||||||
|
|
||||||
try:
|
try:
|
||||||
repo = AlertsRepository(db)
|
config = AlertProcessorConfig()
|
||||||
alert = await repo.get_alert_by_id(tenant_id, alert_id)
|
db_manager = create_database_manager(config.DATABASE_URL, "alert-processor")
|
||||||
|
|
||||||
if not alert:
|
async with db_manager.get_session() as session:
|
||||||
raise HTTPException(status_code=404, detail="Alert not found")
|
repo = AlertsRepository(session)
|
||||||
|
alert = await repo.get_alert_by_id(tenant_id, alert_id)
|
||||||
|
|
||||||
return AlertResponse(
|
if not alert:
|
||||||
id=str(alert.id),
|
raise HTTPException(status_code=404, detail="Alert not found")
|
||||||
tenant_id=str(alert.tenant_id),
|
|
||||||
item_type=alert.item_type,
|
return AlertResponse(
|
||||||
alert_type=alert.alert_type,
|
id=str(alert.id),
|
||||||
severity=alert.severity,
|
tenant_id=str(alert.tenant_id),
|
||||||
status=alert.status,
|
item_type=alert.item_type,
|
||||||
service=alert.service,
|
alert_type=alert.alert_type,
|
||||||
title=alert.title,
|
severity=alert.severity,
|
||||||
message=alert.message,
|
status=alert.status,
|
||||||
actions=alert.actions,
|
service=alert.service,
|
||||||
alert_metadata=alert.alert_metadata,
|
title=alert.title,
|
||||||
created_at=alert.created_at,
|
message=alert.message,
|
||||||
updated_at=alert.updated_at,
|
actions=alert.actions,
|
||||||
resolved_at=alert.resolved_at
|
alert_metadata=alert.alert_metadata,
|
||||||
)
|
created_at=alert.created_at,
|
||||||
|
updated_at=alert.updated_at,
|
||||||
|
resolved_at=alert.resolved_at
|
||||||
|
)
|
||||||
|
|
||||||
except HTTPException:
|
except HTTPException:
|
||||||
raise
|
raise
|
||||||
|
|||||||
Reference in New Issue
Block a user