Repository navigation
Locate Airflow provider info using the provider_info entry point - #3447
NopeCharon wants to merge 2 commits into
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3447 +/- ##
==========================================
+ Coverage 84.82% 84.89% +0.06%
==========================================
Files 159 159
Lines 19297 19351 +54
Branches 500 500
==========================================
+ Hits 16369 16428 +59
+ Misses 2889 2884 -5
Partials 39 39
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
lresende
left a comment
There was a problem hiding this comment.
Thanks for picking this up! Reading the provider_info entry point from the dist-info metadata is the right approach and matches Airflow's provider contract, and the parametrized tests cover the main paths well. There are a few things I'd like to see before merging. First, the package case (my_provider/provider/__init__.py) only works if that __init__.py doesn't import from its own package. The module is still run with exec() in an empty namespace, so from my_provider.version import ... and from .version import ... both fail. The error then lands in the generic outer except with a message that doesn't help the user. Could you catch ImportError around the exec() and log a specific message, or load the module with its package context, and add a test for a provider-info module that has imports? Second, namespace[entry_point.attr] doesn't handle the dotted form (module:Info.get) or an entry point with no :attr (it logs "cannot invoke 'None' method"), so please handle or reject those cases explicitly. Third, it would help to log a deprecation warning when we fall back to get_provider_info.py, since Airflow itself only finds providers through the entry point. Finally, please review docs/source/user_guide/pipeline-components.md for inconsistencies. The intro (line 68) says this connector is "only supported for Airflow < 2", and the provider package section (lines 459–463) marks it "Deprecated in Elyra 4" and "not working in Elyra >=4". But the apache_airflow_provider entry point is an Airflow 2 mechanism, and both the existing and new tests use Airflow 2 provider packages. Please update that section to say which Airflow and Elyra versions the connector actually supports, and mention that it now finds the provider info through the entry point.
The Airflow provider package catalog connector looked for a module named 'get_provider_info.py' in the provider package to determine the modules that define operators. Airflow doesn't require this module name. Provider packages declare the function that returns the provider info as the 'provider_info' entry point in the 'apache_airflow_provider' group, and the function can be defined in any module. Packages that use another module name could not be added to a catalog. Read the entry point from the package's dist-info metadata and load the declared function from its module, which may be a Python script or a package. Packages that don't declare the entry point fall back to the 'get_provider_info.py' module, as before. Fixes elyra-ai#3152 Signed-off-by: NopeCharon <115794254+NopeCharon@users.noreply.github.com>
Run the provider info module with a module name, so that relative imports raise an ImportError, and log a specific error if the module cannot be loaded because it imports from its own package or another package that isn't installed. Resolve entry point attributes that reference a method, such as 'module:Info.get', and log an error if the entry point doesn't reference a function. Log a deprecation warning if the provider info is located using the 'get_provider_info.py' module because the package doesn't declare the 'provider_info' entry point, and document how the connector locates the provider info. Signed-off-by: NopeCharon <115794254+NopeCharon@users.noreply.github.com>
036aa4d to
fbdca08
Compare
|
@lresende Updated in fbdca08: the module now runs with a name so both absolute and relative imports raise ImportError, which is logged with a specific message, |
What changes were proposed in this pull request?
The Airflow provider package catalog connector determines the modules that contain operators from the provider info. To get it, the connector searched the extracted package for a file named
get_provider_info.pyand called itsget_provider_info()function. Airflow doesn't require this name: a provider package declares the function that returns its provider info as theprovider_infoentry point in theapache_airflow_providergroup (Airflow documentation), and the function can be defined in any module. Custom provider packages that use a different module or function name couldn't be added to a catalog. The connector logged that the archive "contains 0 file(s) named 'get_provider_info.py'" and returned no components.This PR adds
_locate_provider_info(), which:provider_infoentry point from the package's*.dist-info/entry_points.txtwithimportlib.metadata.Distribution.at(...), and resolves its module to a script (my_provider/provider.py) or a package (my_provider/provider/__init__.py) in the extracted archive;get_provider_info.py/get_provider_info()if the package doesn't declare the entry point, so existing behavior is preserved for such archives.The rest of the analysis is unchanged. The error message for a missing function now names the function from the entry point, which also drops a stray space from
' get_provider_info'.How was this pull request tested?
New tests in
elyra/tests/pipeline/airflow/test_airflow_provider_package_connector.pybuild small provider wheels and load them throughfile://URLs:test_locate_provider_info: the provider info is found through the entry point in a module with a custom name, through the entry point in a package (__init__.py, with another entry point group present), and throughget_provider_info.pywithout an entry point. In each case the connector returns the operator script. The two entry point cases fail onmain.test_locate_provider_info_errors: an error is logged and no entries are returned if the entry point module isn't in the archive, the entry point function isn't defined, or there's neither an entry point norget_provider_info.py.pytest elyra/tests/pipeline/airflow/test_airflow_provider_package_connector.py: 12 passed, including the existing tests with theapache-airflow-providers-http2.0.2 package, which declares the entry point. I also ran the connector againstapache-airflow-providers-http6.3.0: the provider info is located through the entry point on this branch, and the result is the same as onmain.flake8andblack --checkare clean on the changed files.Fixes #3152
Developer's Certificate of Origin 1.1