You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airflow.apache.org by ur...@apache.org on 2023/03/10 07:24:06 UTC
[airflow] branch main updated: Use custom Connexion resolver to load lazily (#29992)
This is an automated email from the ASF dual-hosted git repository.
uranusjr pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new 7d6afc5857 Use custom Connexion resolver to load lazily (#29992)
7d6afc5857 is described below
commit 7d6afc5857540023a85fb05600c6ce8329492c53
Author: Tzu-ping Chung <ur...@gmail.com>
AuthorDate: Fri Mar 10 15:23:56 2023 +0800
Use custom Connexion resolver to load lazily (#29992)
---
airflow/www/extensions/init_views.py | 35 ++++++++++++++++++++++++++++++++++-
1 file changed, 34 insertions(+), 1 deletion(-)
diff --git a/airflow/www/extensions/init_views.py b/airflow/www/extensions/init_views.py
index 7d32f26959..41408942e4 100644
--- a/airflow/www/extensions/init_views.py
+++ b/airflow/www/extensions/init_views.py
@@ -20,10 +20,11 @@ import logging
import warnings
from os import path
-from connexion import FlaskApi, ProblemException
+from connexion import FlaskApi, ProblemException, Resolver
from flask import Flask, request
from airflow.api_connexion.exceptions import common_error_handler
+from airflow.compat.functools import cached_property
from airflow.configuration import conf
from airflow.exceptions import RemovedInAirflow3Warning
from airflow.security import permissions
@@ -177,6 +178,37 @@ def set_cors_headers_on_response(response):
return response
+class _LazyResolution:
+ """OpenAPI endpoint that lazily resolves the function on first use.
+
+ This is a stand-in replacement for ``connexion.Resolution`` that implements
+ its public attributes ``function`` and ``operation_id``, but the function
+ is only resolved when it is first accessed.
+ """
+
+ def __init__(self, resolve_func, operation_id):
+ self._resolve_func = resolve_func
+ self.operation_id = operation_id
+
+ @cached_property
+ def function(self):
+ return self._resolve_func(self.operation_id)
+
+
+class _LazyResolver(Resolver):
+ """OpenAPI endpoint resolver that loads lazily on first use.
+
+ This re-implements ``connexion.Resolver.resolve()`` to not eagerly resolve
+ the endpoint function (and thus avoid importing it in the process), but only
+ return a placeholder that will be actually resolved when the contained
+ function is accessed.
+ """
+
+ def resolve(self, operation):
+ operation_id = self.resolve_operation_id(operation)
+ return _LazyResolution(self.resolve_function_from_operation_id, operation_id)
+
+
def init_api_connexion(app: Flask) -> None:
"""Initialize Stable API"""
base_path = "/api/v1"
@@ -205,6 +237,7 @@ def init_api_connexion(app: Flask) -> None:
specification = safe_load(f)
api_bp = FlaskApi(
specification=specification,
+ resolver=_LazyResolver(),
base_path=base_path,
options={
"swagger_ui": conf.getboolean("webserver", "enable_swagger_ui", fallback=True),