Coverage for python/pyairflowtester/models.py: 97%
77 statements
« prev ^ index » next coverage.py v7.16.1, created at 2026-09-19 20:43 +0530
« prev ^ index » next coverage.py v7.16.1, created at 2026-09-19 20:43 +0530
1"""
2Data models for PyAirflowTester.
3"""
5from dataclasses import dataclass, field
6from datetime import datetime
7from typing import Any, Dict, List, Optional
9# Severity weights for scoring
10SEVERITY_WEIGHTS = {
11 "critical": 1.0,
12 "high": 0.75,
13 "medium": 0.5,
14 "low": 0.25,
15 "info": 0.1,
16}
19@dataclass
20class Rule:
21 """Rule definition."""
23 id: str
24 name: str
25 severity: str
26 category: str
27 execution_mode: str
28 description: str
29 remediation: str
30 tags: List[str] = field(default_factory=list)
33@dataclass
34class RuleViolation:
35 """Rule violation result."""
37 rule_id: str
38 severity: str
39 affected_resource: str
40 message: str
41 remediation: str
42 context: Dict[str, Any] = field(default_factory=dict)
43 timestamp: datetime = field(default_factory=datetime.utcnow)
45 def to_dict(self) -> Dict[str, Any]:
46 """Convert to dictionary."""
47 return {
48 "rule_id": self.rule_id,
49 "severity": self.severity,
50 "affected_resource": self.affected_resource,
51 "message": self.message,
52 "remediation": self.remediation,
53 "context": self.context,
54 "timestamp": self.timestamp.isoformat(),
55 }
58@dataclass
59class DagDefinition:
60 """Airflow DAG definition."""
62 dag_id: str
63 file_path: str
64 source_code: str
65 parse_time_ms: float = 0.0
66 task_count: int = 0
67 task_ids: List[str] = field(default_factory=list)
68 max_task_depth: int = 0
69 has_cycles: bool = False
70 dynamic_dag_detected: bool = False
71 expensive_imports: List[str] = field(default_factory=list)
72 external_dependencies: List[str] = field(default_factory=list)
75@dataclass
76class DbtModel:
77 """dbt model definition."""
79 name: str
80 materialization: str = "table"
81 description: str = ""
82 columns: List[str] = field(default_factory=list)
83 tests: List[str] = field(default_factory=list)
84 downstream_models: List[str] = field(default_factory=list)
85 upstream_models: List[str] = field(default_factory=list)
86 source_file: str = ""
89@dataclass
90class DbtTest:
91 """dbt test definition."""
93 name: str
94 test_type: str
95 model_name: str
96 source_name: Optional[str] = None
97 column_name: Optional[str] = None
98 properties: Dict[str, str] = field(default_factory=dict)
101@dataclass
102class RiskScorecard:
103 """Risk scorecard for a resource."""
105 resource_id: str
106 resource_type: str
107 timestamp: datetime = field(default_factory=datetime.utcnow)
108 reliability_score: float = 75.0
109 performance_score: float = 75.0
110 maintainability_score: float = 75.0
111 security_score: float = 75.0
112 cost_efficiency_score: float = 75.0
113 overall_health_score: float = 75.0
114 risk_level: str = "medium"
116 def to_dict(self) -> Dict[str, Any]:
117 """Convert to dictionary."""
118 return {
119 "resource_id": self.resource_id,
120 "resource_type": self.resource_type,
121 "timestamp": self.timestamp.isoformat(),
122 "reliability_score": self.reliability_score,
123 "performance_score": self.performance_score,
124 "maintainability_score": self.maintainability_score,
125 "security_score": self.security_score,
126 "cost_efficiency_score": self.cost_efficiency_score,
127 "overall_health_score": self.overall_health_score,
128 "risk_level": self.risk_level,
129 }
132@dataclass
133class AnalysisContext:
134 """Context for analysis."""
136 dag_id: Optional[str] = None
137 task_id: Optional[str] = None
138 model_name: Optional[str] = None
139 test_id: Optional[str] = None
140 metadata: Dict[str, str] = field(default_factory=dict)