Skip to content

Commit 9da6fc3

Browse files
authored
Remove the ability to import executors from plugins (#43289)
Executors should no longer be registered or imported via Airflow's plugin mechanism -- these types of classes are just treated as plain python classes by Airflow, so there is no need to register them with Airflow.
1 parent d7f50ba commit 9da6fc3

14 files changed

Lines changed: 7 additions & 124 deletions

File tree

airflow/api_fastapi/core_api/openapi/v1-generated.yaml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2212,11 +2212,6 @@ components:
22122212
type: string
22132213
type: array
22142214
title: Hooks
2215-
executors:
2216-
items:
2217-
type: string
2218-
type: array
2219-
title: Executors
22202215
macros:
22212216
items:
22222217
type: string
@@ -2274,7 +2269,6 @@ components:
22742269
required:
22752270
- name
22762271
- hooks
2277-
- executors
22782272
- macros
22792273
- flask_blueprints
22802274
- fastapi_apps

airflow/api_fastapi/core_api/serializers/plugins.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ class PluginResponse(BaseModel):
6565

6666
name: str
6767
hooks: list[str]
68-
executors: list[str]
6968
macros: list[str]
7069
flask_blueprints: list[str]
7170
fastapi_apps: list[FastAPIAppResponse]

airflow/executors/executor_loader.py

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import functools
2222
import logging
2323
import os
24-
from contextlib import suppress
2524
from typing import TYPE_CHECKING
2625

2726
from airflow.api_internal.internal_api_call import InternalApiConfig
@@ -284,17 +283,6 @@ def _import_and_validate(path: str) -> type[BaseExecutor]:
284283
cls.validate_database_executor_compatibility(executor)
285284
return executor
286285

287-
if executor_name.connector_source == ConnectorSource.PLUGIN:
288-
with suppress(ImportError, AttributeError):
289-
# Load plugins here for executors as at that time the plugins might not have been
290-
# initialized yet
291-
from airflow import plugins_manager
292-
293-
plugins_manager.integrate_executor_plugins()
294-
return (
295-
_import_and_validate(f"airflow.executors.{executor_name.module_path}"),
296-
ConnectorSource.PLUGIN,
297-
)
298286
return _import_and_validate(executor_name.module_path), executor_name.connector_source
299287

300288
@classmethod

airflow/plugins_manager.py

Lines changed: 1 addition & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@
6464
# Plugin components to integrate as modules
6565
registered_hooks: list[BaseHook] | None = None
6666
macros_modules: list[Any] | None = None
67-
executors_modules: list[Any] | None = None
6867

6968
# Plugin components to integrate directly
7069
admin_views: list[Any] | None = None
@@ -88,7 +87,6 @@
8887
"""
8988
PLUGINS_ATTRIBUTES_TO_DUMP = {
9089
"hooks",
91-
"executors",
9290
"macros",
9391
"admin_views",
9492
"flask_blueprints",
@@ -154,7 +152,6 @@ class AirflowPlugin:
154152
name: str | None = None
155153
source: AirflowPluginSource | None = None
156154
hooks: list[Any] = []
157-
executors: list[Any] = []
158155
macros: list[Any] = []
159156
admin_views: list[Any] = []
160157
flask_blueprints: list[Any] = []
@@ -533,33 +530,6 @@ def initialize_hook_lineage_readers_plugins():
533530
hook_lineage_reader_classes.extend(plugin.hook_lineage_readers)
534531

535532

536-
def integrate_executor_plugins() -> None:
537-
"""Integrate executor plugins to the context."""
538-
global plugins
539-
global executors_modules
540-
541-
if executors_modules is not None:
542-
return
543-
544-
ensure_plugins_loaded()
545-
546-
if plugins is None:
547-
raise AirflowPluginException("Can't load plugins.")
548-
549-
log.debug("Integrate executor plugins")
550-
551-
executors_modules = []
552-
for plugin in plugins:
553-
if plugin.name is None:
554-
raise AirflowPluginException("Invalid plugin name")
555-
plugin_name: str = plugin.name
556-
557-
executors_module = make_module("airflow.executors." + plugin_name, plugin.executors)
558-
if executors_module:
559-
executors_modules.append(executors_module)
560-
sys.modules[executors_module.__name__] = executors_module
561-
562-
563533
def integrate_macros_plugins() -> None:
564534
"""Integrates macro plugins."""
565535
global plugins
@@ -615,7 +585,6 @@ def get_plugin_info(attrs_to_dump: Iterable[str] | None = None) -> list[dict[str
615585
:param attrs_to_dump: A list of plugin attributes to dump
616586
"""
617587
ensure_plugins_loaded()
618-
integrate_executor_plugins()
619588
integrate_macros_plugins()
620589
initialize_web_ui_plugins()
621590
initialize_fastapi_plugins()
@@ -629,7 +598,7 @@ def get_plugin_info(attrs_to_dump: Iterable[str] | None = None) -> list[dict[str
629598
for attr in attrs_to_dump:
630599
if attr in ("global_operator_extra_links", "operator_extra_links"):
631600
info[attr] = [f"<{qualname(d.__class__)} object>" for d in getattr(plugin, attr)]
632-
elif attr in ("macros", "timetables", "hooks", "executors", "priority_weight_strategies"):
601+
elif attr in ("macros", "timetables", "hooks", "priority_weight_strategies"):
633602
info[attr] = [qualname(d) for d in getattr(plugin, attr)]
634603
elif attr == "listeners":
635604
# listeners may be modules or class instances

airflow/ui/openapi-gen/requests/schemas.gen.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1333,13 +1333,6 @@ export const $PluginResponse = {
13331333
type: "array",
13341334
title: "Hooks",
13351335
},
1336-
executors: {
1337-
items: {
1338-
type: "string",
1339-
},
1340-
type: "array",
1341-
title: "Executors",
1342-
},
13431336
macros: {
13441337
items: {
13451338
type: "string",
@@ -1419,7 +1412,6 @@ export const $PluginResponse = {
14191412
required: [
14201413
"name",
14211414
"hooks",
1422-
"executors",
14231415
"macros",
14241416
"flask_blueprints",
14251417
"fastapi_apps",

airflow/ui/openapi-gen/requests/types.gen.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,6 @@ export type PluginCollectionResponse = {
311311
export type PluginResponse = {
312312
name: string;
313313
hooks: Array<string>;
314-
executors: Array<string>;
315314
macros: Array<string>;
316315
flask_blueprints: Array<string>;
317316
fastapi_apps: Array<FastAPIAppResponse>;

airflow/www/views.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4286,7 +4286,6 @@ class PluginView(AirflowBaseView):
42864286
def list(self):
42874287
"""List loaded plugins."""
42884288
plugins_manager.ensure_plugins_loaded()
4289-
plugins_manager.integrate_executor_plugins()
42904289
plugins_manager.initialize_extra_operators_links_plugins()
42914290
plugins_manager.initialize_web_ui_plugins()
42924291
plugins_manager.initialize_fastapi_plugins()
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Support for adding executors via Airflow Plugins is removed
2+
3+
Executors should no longer be registered or imported via Airflow's plugin mechanism -- these types of classes
4+
are just treated as plain Python classes by Airflow, so there is no need to register them with Airflow.

tests/api_connexion/endpoints/test_plugin_endpoint.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,6 @@ def test_get_plugins_return_200(self):
145145
{
146146
"appbuilder_menu_items": [appbuilder_menu_items],
147147
"appbuilder_views": [{"view": qualname(MockView)}],
148-
"executors": [],
149148
"flask_blueprints": [
150149
f"<{qualname(bp.__class__)}: name={bp.name!r} import_name={bp.import_name!r}>"
151150
],

tests/api_connexion/schemas/test_plugin_schema.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ def test_serialize(self):
8686
assert deserialized_plugin == {
8787
"appbuilder_menu_items": [appbuilder_menu_items],
8888
"appbuilder_views": [{"view": self.mock_plugin.appbuilder_views[0]["view"]}],
89-
"executors": [],
9089
"flask_blueprints": [str(bp)],
9190
"fastapi_apps": [
9291
{"app": app, "name": "App name", "url_prefix": "/some_prefix"},
@@ -113,7 +112,6 @@ def test_serialize(self):
113112
{
114113
"appbuilder_menu_items": [appbuilder_menu_items],
115114
"appbuilder_views": [{"view": self.mock_plugin.appbuilder_views[0]["view"]}],
116-
"executors": [],
117115
"flask_blueprints": [str(bp)],
118116
"fastapi_apps": [
119117
{"app": app, "name": "App name", "url_prefix": "/some_prefix"},
@@ -131,7 +129,6 @@ def test_serialize(self):
131129
{
132130
"appbuilder_menu_items": [appbuilder_menu_items],
133131
"appbuilder_views": [{"view": self.mock_plugin.appbuilder_views[0]["view"]}],
134-
"executors": [],
135132
"flask_blueprints": [str(bp)],
136133
"fastapi_apps": [
137134
{"app": app, "name": "App name", "url_prefix": "/some_prefix"},

0 commit comments

Comments
 (0)