0
# Version Compatibility
1
2
Cross-version compatibility utilities ensuring seamless operation across different Apache Airflow versions. Provides version detection and consistent access to base classes while maintaining backward compatibility.
3
4
## Capabilities
5
6
### Version Detection
7
8
Utility functions to detect the current Airflow version and determine feature availability.
9
10
```python { .api }
11
def get_base_airflow_version_tuple() -> tuple[int, int, int]:
12
"""
13
Get the base Airflow version as a tuple of integers.
14
15
Extracts major, minor, and micro version numbers from the current
16
Airflow installation, ignoring pre-release suffixes.
17
18
Returns:
19
tuple: (major, minor, micro) version numbers
20
21
Example:
22
For Airflow 2.10.1rc1, returns (2, 10, 1)
23
For Airflow 3.0.0, returns (3, 0, 0)
24
"""
25
```
26
27
**Usage Example:**
28
29
```python
30
from airflow.providers.microsoft.winrm.version_compat import get_base_airflow_version_tuple
31
32
version = get_base_airflow_version_tuple()
33
print(f"Running Airflow {version[0]}.{version[1]}.{version[2]}")
34
35
if version >= (3, 0, 0):
36
print("Using Airflow 3.0+ features")
37
elif version >= (2, 10, 0):
38
print("Using Airflow 2.10+ features")
39
```
40
41
### Version Flags
42
43
Boolean constants indicating Airflow version capabilities for conditional feature usage.
44
45
```python { .api }
46
AIRFLOW_V_3_0_PLUS: bool
47
"""True if running Airflow 3.0.0 or later, False otherwise."""
48
49
AIRFLOW_V_3_1_PLUS: bool
50
"""True if running Airflow 3.1.0 or later, False otherwise."""
51
```
52
53
**Usage Examples:**
54
55
```python
56
from airflow.providers.microsoft.winrm.version_compat import AIRFLOW_V_3_0_PLUS, AIRFLOW_V_3_1_PLUS
57
58
# Conditional feature usage
59
if AIRFLOW_V_3_0_PLUS:
60
# Use Airflow 3.0+ specific features
61
print("Using enhanced task execution features")
62
else:
63
# Fallback for Airflow 2.x
64
print("Using legacy task execution")
65
66
# Version-specific imports
67
if AIRFLOW_V_3_1_PLUS:
68
from airflow.sdk.execution import TaskExecutionContext
69
else:
70
from airflow.models import TaskInstance as TaskExecutionContext
71
```
72
73
### Base Class Compatibility
74
75
Version-aware imports providing consistent access to fundamental Airflow base classes across different versions.
76
77
```python { .api }
78
BaseOperator: type
79
"""
80
Base operator class for creating Airflow tasks.
81
- Airflow 3.0+: Imported from airflow.sdk.BaseOperator
82
- Airflow 2.x: Imported from airflow.models.BaseOperator
83
"""
84
85
BaseHook: type
86
"""
87
Base hook class for creating Airflow connections.
88
- Airflow 3.1+: Imported from airflow.sdk.BaseHook
89
- Airflow 2.x/3.0: Imported from airflow.hooks.base.BaseHook
90
"""
91
```
92
93
**Usage Examples:**
94
95
```python
96
from airflow.providers.microsoft.winrm.version_compat import BaseHook, BaseOperator
97
98
# Create custom hook extending BaseHook
99
class CustomWinRMHook(BaseHook):
100
def __init__(self, connection_id: str):
101
super().__init__()
102
self.connection_id = connection_id
103
104
def get_conn(self):
105
# Implementation here
106
pass
107
108
# Create custom operator extending BaseOperator
109
class CustomWinRMOperator(BaseOperator):
110
def __init__(self, custom_param: str, **kwargs):
111
super().__init__(**kwargs)
112
self.custom_param = custom_param
113
114
def execute(self, context):
115
# Implementation here
116
pass
117
```
118
119
### Provider Information
120
121
Get provider metadata and configuration details.
122
123
```python { .api }
124
def get_provider_info() -> dict:
125
"""
126
Get provider information including version, dependencies, and configuration.
127
128
Returns:
129
dict: Provider metadata including name, version, description,
130
connection types, and hook/operator class names
131
"""
132
```
133
134
### Package Exports
135
136
Complete list of exported symbols for version compatibility module.
137
138
```python { .api }
139
__all__ = [
140
"AIRFLOW_V_3_0_PLUS",
141
"AIRFLOW_V_3_1_PLUS",
142
"BaseOperator",
143
"BaseHook",
144
]
145
```
146
147
## Version Migration Guide
148
149
### Airflow 2.10 to 3.0 Migration
150
151
**Key Changes:**
152
- `BaseOperator` moved from `airflow.models` to `airflow.sdk`
153
- Task execution context changes
154
- Enhanced task lifecycle management
155
156
**Code Compatibility:**
157
```python
158
# This works across versions
159
from airflow.providers.microsoft.winrm.version_compat import BaseOperator
160
161
class MyOperator(BaseOperator):
162
def execute(self, context):
163
# Context handling works across versions
164
task_instance = context['task_instance']
165
return "success"
166
```
167
168
### Airflow 3.0 to 3.1 Migration
169
170
**Key Changes:**
171
- `BaseHook` moved from `airflow.hooks.base` to `airflow.sdk`
172
- Enhanced connection management
173
- Improved hook lifecycle
174
175
**Code Compatibility:**
176
```python
177
# This works across versions
178
from airflow.providers.microsoft.winrm.version_compat import BaseHook
179
180
class MyHook(BaseHook):
181
def get_conn(self):
182
# Connection handling works across versions
183
conn = self.get_connection(self.conn_id)
184
return create_connection(conn)
185
```
186
187
## Implementation Details
188
189
### Version Detection Logic
190
191
The module uses `packaging.version` for robust version parsing:
192
193
```python
194
from packaging.version import Version
195
from airflow import __version__
196
197
airflow_version = Version(__version__)
198
major, minor, micro = airflow_version.major, airflow_version.minor, airflow_version.micro
199
```
200
201
### Import Strategy
202
203
The module employs conditional imports based on detected version:
204
205
```python
206
# For BaseOperator
207
if AIRFLOW_V_3_0_PLUS:
208
from airflow.sdk import BaseOperator
209
else:
210
from airflow.models import BaseOperator
211
212
# For BaseHook
213
if AIRFLOW_V_3_1_PLUS:
214
from airflow.sdk import BaseHook
215
else:
216
from airflow.hooks.base import BaseHook
217
```
218
219
### Compatibility Testing
220
221
The provider package is tested against multiple Airflow versions:
222
- Airflow 2.10.x (minimum supported)
223
- Airflow 3.0.x (major version transition)
224
- Airflow 3.1.x (latest features)
225
226
## Error Handling
227
228
### Version Requirement Enforcement
229
230
The main package `__init__.py` enforces minimum version requirements:
231
232
```python
233
if packaging.version.parse(packaging.version.parse(airflow_version).base_version) < packaging.version.parse("2.10.0"):
234
raise RuntimeError(
235
f"The package `apache-airflow-providers-microsoft-winrm:{__version__}` needs Apache Airflow 2.10.0+"
236
)
237
```
238
239
### Import Failures
240
241
If version detection fails, the module falls back to legacy imports with appropriate error messages for unsupported versions.
242
243
## Best Practices
244
245
### Using Version Compatibility
246
247
1. **Always use version_compat imports** for base classes instead of direct imports
248
2. **Check version flags** before using version-specific features
249
3. **Test across supported versions** when extending the provider
250
4. **Handle version differences gracefully** in custom implementations
251
252
### Example: Version-Aware Custom Hook
253
254
```python
255
from airflow.providers.microsoft.winrm.version_compat import BaseHook, AIRFLOW_V_3_1_PLUS
256
257
class AdvancedWinRMHook(BaseHook):
258
def __init__(self, conn_id: str):
259
super().__init__()
260
self.conn_id = conn_id
261
262
def get_conn(self):
263
if AIRFLOW_V_3_1_PLUS:
264
# Use enhanced connection features
265
conn = self.get_connection(self.conn_id, include_secrets=True)
266
else:
267
# Use standard connection
268
conn = self.get_connection(self.conn_id)
269
270
return self._create_winrm_connection(conn)
271
```
272
273
This approach ensures your custom extensions work seamlessly across all supported Airflow versions.