You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airflow.apache.org by "Lee-W (via GitHub)" <gi...@apache.org> on 2026/07/21 12:54:27 UTC
[PR] Add more provider module categories to the provider page [airflow]
Lee-W opened a new pull request, #70190:
URL: https://github.com/apache/airflow/pull/70190
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->
<!--
Thank you for contributing!
Please provide above a brief description of the changes made in this pull request.
Write a good git commit message following this guide: https://chris.beams.io/posts/git-commit/
Please make sure that your code changes are covered with tests.
And in case of new features or big changes remember to adjust the documentation.
For user-facing UI changes, please attach before/after screenshots (or a short
screen recording) so reviewers can assess the visual impact.
Feel free to ping (in general) for the review if you do not see reaction for a few days
(72 Hours is the minimum reaction time you can expect from volunteers) - we sometimes miss notifications.
In case of an existing issue, reference it using one of the following:
* closes: #ISSUE
* related: #ISSUE
-->
---
##### Was generative AI tooling used to co-author this PR?
<!--
If generative AI tooling has been used in the process of authoring this PR, please
change below checkbox to `[X]` followed by the name of the tool, uncomment the "Generated-by".
-->
- [ ] Yes (please specify the tool below)
<!--
Generated-by: [Tool Name] following [the guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions)
-->
---
* Read the **[Pull Request Guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#pull-request-guidelines)** for more information. Note: commit author/co-author name and email in commits become permanently public when merged.
* For fundamental code changes, an Airflow Improvement Proposal ([AIP](https://cwiki.apache.org/confluence/display/AIRFLOW/Airflow+Improvement+Proposals)) is needed.
* When adding dependency, check compliance with the [ASF 3rd Party License Policy](https://www.apache.org/legal/resolved.html#category-x).
* For significant user-facing changes create newsfragment: `{pr_number}.significant.rst`, in [airflow-core/newsfragments](https://github.com/apache/airflow/tree/main/airflow-core/newsfragments). You can add this file in a follow-up commit after the PR is created so you know the PR number.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Add more provider module categories to the provider page [airflow]
Posted by "uranusjr (via GitHub)" <gi...@apache.org>.
uranusjr commented on code in PR #70190:
URL: https://github.com/apache/airflow/pull/70190#discussion_r3689976422
##########
dev/registry/registry_tools/types.py:
##########
@@ -116,6 +116,48 @@
"label": "Retry Policies",
"icon": "R",
},
+ "extra_link": {
+ "yaml_key": "extra-links",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Extra Links",
+ "icon": "I",
+ },
+ "queue": {
+ "yaml_key": "queues",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Message Queues",
+ "icon": "Q",
+ },
+ "plugin": {
+ "yaml_key": "plugins",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Plugins",
+ "icon": "P",
+ },
+ "auth_manager": {
+ "yaml_key": "auth-managers",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Auth Managers",
+ "icon": "A",
+ },
+ "db_manager": {
+ "yaml_key": "db-managers",
+ "level": "flat",
+ "suffixes": [],
+ "label": "DB Managers",
+ "icon": "D",
+ },
+ "dialect": {
+ "yaml_key": "dialects",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Dialects",
+ "icon": "C",
Review Comment:
I wonder if we want to choose a different letter since C might be useful for connection. Or maybe db_manager can use M instead? Not sure.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Add more provider module categories to the provider page [airflow]
Posted by "Lee-W (via GitHub)" <gi...@apache.org>.
Lee-W commented on code in PR #70190:
URL: https://github.com/apache/airflow/pull/70190#discussion_r3627055596
##########
dev/registry/registry_tools/types.py:
##########
@@ -109,6 +109,48 @@
"label": "Toolsets",
"icon": "U",
},
+ "extra_link": {
+ "yaml_key": "extra-links",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Extra Links",
+ "icon": "I",
+ },
+ "queue": {
+ "yaml_key": "queues",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Queues",
+ "icon": "Q",
Review Comment:
consolidate the discussion in https://github.com/apache/airflow/pull/70190#discussion_r3627054316
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Add more provider module categories to the provider page [airflow]
Posted by "uranusjr (via GitHub)" <gi...@apache.org>.
uranusjr commented on code in PR #70190:
URL: https://github.com/apache/airflow/pull/70190#discussion_r3689936287
##########
dev/registry/registry_tools/types.py:
##########
@@ -147,11 +189,39 @@
# Class-level sections used by extract_parameters.py (subset of flat that
# list full class paths rather than simple entries).
+#
+# "plugins" and "dialects" are also flat/class-path sections, but each entry is a
+# dict (plugin-class / dialect-class-name) rather than a bare string, and the
+# integration-name field they carry differs between the two, so extract_parameters.py
+# still walks them with their own loops instead of this generic one. The class-path
+# field name itself is shared via DICT_SHAPED_CLASS_LEVEL_SECTIONS below so both
+# extract_versions.py and extract_parameters.py read it from one place.
CLASS_LEVEL_SECTIONS: dict[str, str] = {
"notifications": "notifier",
"secrets-backends": "secret",
"logging": "logging",
"executors": "executor",
+ "extra-links": "extra_link",
+ "queues": "queue",
+ "auth-managers": "auth_manager",
+ "db-managers": "db_manager",
+}
+
+# Maps yaml section key -> (type id, class-path field name) for dict-shaped
+# class-level sections (each yaml entry is a dict, not a bare class-path
+# string), shared by extract_versions.py and extract_parameters.py so the
+# field name is defined exactly once.
+DICT_SHAPED_CLASS_LEVEL_SECTIONS: dict[str, tuple[str, str]] = {
+ "plugins": ("plugin", "plugin-class"),
+ "dialects": ("dialect", "dialect-class-name"),
+}
Review Comment:
I think this can have a third component `name` and `dialect-type` instead, so `discover_classes_from_provider` only needs one loop instead of two.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Add more provider module categories to the provider page [airflow]
Posted by "kaxil (via GitHub)" <gi...@apache.org>.
kaxil commented on code in PR #70190:
URL: https://github.com/apache/airflow/pull/70190#discussion_r3682598643
##########
registry/src/js/provider-detail.js:
##########
@@ -155,6 +157,44 @@
});
});
+ // "More" overflow menu for module tabs that don't fit in the visible row.
+ var moduleTabMoreBtn = document.getElementById('module-tab-more-btn');
+ var moduleTabMoreMenu = document.getElementById('module-tab-more-menu');
+
+ if (moduleTabMoreBtn && moduleTabMoreMenu) {
+ function closeMoreMenu() {
+ moduleTabMoreBtn.setAttribute('aria-expanded', 'false');
+ moduleTabMoreMenu.hidden = true;
+ }
+
+ moduleTabMoreBtn.addEventListener('click', function(e) {
+ e.stopPropagation();
+ var isOpen = moduleTabMoreBtn.getAttribute('aria-expanded') === 'true';
+ if (isOpen) {
+ closeMoreMenu();
+ } else {
+ moduleTabMoreBtn.setAttribute('aria-expanded', 'true');
+ moduleTabMoreMenu.hidden = false;
+ }
+ });
+
+ document.addEventListener('click', function(e) {
+ if (!moduleTabMoreMenu.contains(e.target) && e.target !== moduleTabMoreBtn) {
+ closeMoreMenu();
+ }
+ });
+
+ document.addEventListener('keydown', function(e) {
+ if (e.key === 'Escape') closeMoreMenu();
+ });
+
+ // Selecting a tab inside the menu also closes it (filtering itself is
+ // handled by the shared moduleTabs click listener above).
+ moduleTabMoreMenu.querySelectorAll('.module-tab').forEach(function(tab) {
+ tab.addEventListener('click', closeMoreMenu);
Review Comment:
The shared `moduleTabs` listener does `moduleTabs.forEach(t => t.classList.remove('active'))` and then marks the clicked tab, and the tab clicked here is inside the menu that just got hidden. So after picking Dialects from More, no visible tab is highlighted (All lost `active` too) and there's nothing showing what the list is filtered by. Adding `active` to the More button when the selected type is in `overflowTypes` would cover it.
##########
registry/src/_data/types.json:
##########
@@ -58,5 +58,35 @@
"id": "toolset",
"label": "Toolsets",
"icon": "U"
+ },
+ {
+ "id": "extra_link",
Review Comment:
Each entry here feeds more CSS than `.tab-icon.<id>`. `_data/statsData.js` builds one stats card per types.json entry with `colorClass: t.id` and no zero-count filter, so `/stats/` needs `.type-icon.<id>` and `.share-bar.<id>`; `provider-card.njk`'s breakdown bar needs `.provider-card .modules .<id>`. All three families stop at `decorator` in main.css, so the six new ids get transparent slices in the listing-page breakdown bar (`.breakdown > div` has no default background, though widths still sum to 100% and tooltips still work), six 2.5rem chips on `/stats/` with no background or icon colour, and gray share-bars since `--meter-color` falls back to `--color-gray-500`.
The `--color-*` tokens are already added in tokens.css, so it's one line per id in each of the three blocks. `toolset` has the same gap from #70122.
##########
dev/registry/registry_tools/types.py:
##########
@@ -139,11 +181,27 @@
# Class-level sections used by extract_parameters.py (subset of flat that
# list full class paths rather than simple entries).
+#
+# "plugins" and "dialects" are also flat/class-path sections, but each entry is a
+# dict (plugin-class / dialect-class-name) rather than a bare string, so they are
+# handled by their own loops in extract_parameters.py instead of this generic one.
CLASS_LEVEL_SECTIONS: dict[str, str] = {
"notifications": "notifier",
"secrets-backends": "secret",
"logging": "logging",
"executors": "executor",
+ "extra-links": "extra_link",
+ "queues": "queue",
Review Comment:
Worth a follow-up outside this PR: `provider.yaml.schema.json` declares `queues` items as `{name, message-queue-class}`, the same shape as `plugins`, but all six providers that set it list a bare class path, which is what this treats them as. The `items` block has no `type` key, so neither shape is actually validated. Since this is the first consumer of the section, tightening it to `items: {type: string}` would stop a future provider following the documented dict shape from being silently dropped by the `isinstance(class_path, str)` guard in extract_parameters.py.
##########
dev/registry/extract_versions.py:
##########
@@ -300,15 +320,13 @@ def process_module(module_path: str, module_type: str, integration: str, categor
if mp:
process_module(mp, "transfer", source, get_category(source))
- # Class-level sections (full class paths, no source file parsing needed)
- FQCN_SECTIONS: dict[str, tuple[str, str, str]] = {
- # yaml_key: (module_type, category, description_suffix)
- "notifications": ("notifier", "notifications", "notifier"),
- "secrets-backends": ("secret", "secrets", "secrets backend"),
- "logging": ("logging", "logging", "log handler"),
- "executors": ("executor", "executors", "executor"),
- }
- for yaml_key, (mod_type, category, desc_suffix) in FQCN_SECTIONS.items():
+ # Class-level sections (full class paths, no source file parsing needed).
+ # Iterating CLASS_LEVEL_SECTIONS keeps this in sync with the single
+ # source of truth in types.py; a section added there without a matching
+ # FQCN_DESC_SUFFIXES entry raises KeyError instead of silently skipping.
+ for yaml_key, mod_type in CLASS_LEVEL_SECTIONS.items():
Review Comment:
Good that this tracks `CLASS_LEVEL_SECTIONS` now, but `plugins` and `dialects` are deliberately excluded from that dict (dict-shaped entries), and they only get their own loops in `extract_parameters.py`. So version pages built here still miss those two types while the latest page has them: postgres, common.sql and microsoft.mssql get a Dialects tab on latest and nothing on older versions, same for the seven providers with `plugins` (databricks, edge3, informatica, openlineage, apache.hive, apache.kafka, common.ai).
`test_all_class_level_sections_produce_covered_types` won't catch it either, since it iterates the same dict.
##########
registry/src/js/provider-detail.js:
##########
@@ -155,6 +157,44 @@
});
});
+ // "More" overflow menu for module tabs that don't fit in the visible row.
+ var moduleTabMoreBtn = document.getElementById('module-tab-more-btn');
+ var moduleTabMoreMenu = document.getElementById('module-tab-more-menu');
+
+ if (moduleTabMoreBtn && moduleTabMoreMenu) {
+ function closeMoreMenu() {
+ moduleTabMoreBtn.setAttribute('aria-expanded', 'false');
+ moduleTabMoreMenu.hidden = true;
+ }
+
+ moduleTabMoreBtn.addEventListener('click', function(e) {
+ e.stopPropagation();
+ var isOpen = moduleTabMoreBtn.getAttribute('aria-expanded') === 'true';
+ if (isOpen) {
+ closeMoreMenu();
+ } else {
+ moduleTabMoreBtn.setAttribute('aria-expanded', 'true');
+ moduleTabMoreMenu.hidden = false;
+ }
+ });
+
+ document.addEventListener('click', function(e) {
+ if (!moduleTabMoreMenu.contains(e.target) && e.target !== moduleTabMoreBtn) {
+ closeMoreMenu();
+ }
+ });
+
+ document.addEventListener('keydown', function(e) {
+ if (e.key === 'Escape') closeMoreMenu();
Review Comment:
If focus is inside the menu when Escape fires, setting `hidden` drops focus to `<body>`. A `moduleTabMoreBtn.focus()` inside `closeMoreMenu` keeps it on the trigger. Related: `role="menu"` / `role="menuitem"` implies arrow-key navigation, which isn't wired up, so dropping the roles may be the easier promise to keep.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Add more provider module categories to the provider page [airflow]
Posted by "Lee-W (via GitHub)" <gi...@apache.org>.
Lee-W commented on code in PR #70190:
URL: https://github.com/apache/airflow/pull/70190#discussion_r3627059419
##########
dev/registry/extract_parameters.py:
##########
@@ -586,6 +586,10 @@ def make_entry(
"secrets-backends": "secrets",
"logging": "logging",
"executors": "executors",
+ "extra-links": "extra-links",
+ "queues": "queues",
+ "auth-managers": "auth-managers",
+ "db-managers": "db-managers",
Review Comment:
sounds good. also removed logging and executors above
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Add more provider module categories to the provider page [airflow]
Posted by "kaxil (via GitHub)" <gi...@apache.org>.
kaxil commented on code in PR #70190:
URL: https://github.com/apache/airflow/pull/70190#discussion_r3706820021
##########
dev/registry/tests/test_types.py:
##########
@@ -93,6 +95,14 @@ def test_class_level_sections_are_subset_of_flat(self):
assert yaml_key in FLAT_LEVEL_SECTIONS
assert FLAT_LEVEL_SECTIONS[yaml_key] == type_id
+ def test_class_level_category_overrides_are_subset_of_class_level_sections(self):
+ assert set(CLASS_LEVEL_CATEGORY_OVERRIDES.keys()) <= set(CLASS_LEVEL_SECTIONS.keys())
+
+ def test_dict_shaped_class_level_sections_are_subset_of_flat(self):
Review Comment:
This and the sibling above check the subset direction, but the failure mode from last round was the other one: a flat section that neither table consumes gets silently skipped by both extractors, and the `FQCN_DESC_SUFFIXES[mod_type]` KeyError can't catch it, since it only fires for keys already in a table. `set(FLAT_LEVEL_SECTIONS)` is exactly `set(CLASS_LEVEL_SECTIONS) | set(DICT_SHAPED_CLASS_LEVEL_SECTIONS) | {"transfers", "task-decorators"}` today, so asserting that equality passes now and fails loudly next time.
##########
registry/src/_data/types.json:
##########
@@ -63,5 +63,35 @@
"id": "retry_policy",
"label": "Retry Policies",
"icon": "R"
+ },
+ {
+ "id": "extra_link",
+ "label": "Extra Links",
+ "icon": "I"
+ },
+ {
+ "id": "queue",
+ "label": "Message Queues",
+ "icon": "Q"
+ },
+ {
+ "id": "plugin",
+ "label": "Plugins",
+ "icon": "P"
+ },
+ {
+ "id": "auth_manager",
+ "label": "Auth Managers",
+ "icon": "A"
+ },
+ {
+ "id": "db_manager",
+ "label": "DB Managers",
+ "icon": "M"
Review Comment:
The M here doesn't reach the module cards. `provider-version.njk:374` renders the card chip as `{{ module.type[0] | upper }}` instead of reading this file, so `db_manager` cards show D, colliding with `decorator` and `dialect` -- the collision `ff18815f` was written to avoid. Six of the 19 ids disagree with their curated letter that way (`transfer` X->T, `secret` K->S, `decorator` @->D, `toolset` U->T, `extra_link` I->E, `db_manager` M->D).
The same block also misses colour: `.provider-detail-page .modules .module .icon.<id>` covers 6 of 19 ids and the base `.icon` rule sets no background, so those cards get a transparent chip. Both halves already affect `secret`, `decorator` and `toolset`, so a follow-up is fine, but a small `typeIcon` lookup filter beside `sortTypesByCount` would let the card read from here the way the tabs already do.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Add more provider module categories to the provider page [airflow]
Posted by "kaxil (via GitHub)" <gi...@apache.org>.
kaxil commented on code in PR #70190:
URL: https://github.com/apache/airflow/pull/70190#discussion_r3632722949
##########
dev/registry/registry_tools/types.py:
##########
@@ -109,6 +109,48 @@
"label": "Toolsets",
"icon": "U",
},
+ "extra_link": {
+ "yaml_key": "extra-links",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Extra Links",
+ "icon": "I",
+ },
+ "queue": {
+ "yaml_key": "queues",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Queues",
+ "icon": "Q",
+ },
+ "plugin": {
+ "yaml_key": "plugins",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Plugins",
+ "icon": "P",
+ },
+ "auth_manager": {
+ "yaml_key": "auth-managers",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Auth Managers",
+ "icon": "A",
+ },
+ "db_manager": {
+ "yaml_key": "db-managers",
+ "level": "flat",
+ "suffixes": [],
+ "label": "DB Managers",
+ "icon": "D",
+ },
+ "dialect": {
+ "yaml_key": "dialects",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Dialects",
+ "icon": "C",
+ },
Review Comment:
Aah **Message Queues** -- I think we should relabel it to "**Message Queues**" so folks aren't confused with things like "queue" argument on Base Operator.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Add more provider module categories to the provider page [airflow]
Posted by "phanikumv (via GitHub)" <gi...@apache.org>.
phanikumv commented on code in PR #70190:
URL: https://github.com/apache/airflow/pull/70190#discussion_r3623864506
##########
dev/registry/extract_parameters.py:
##########
@@ -586,6 +586,10 @@ def make_entry(
"secrets-backends": "secrets",
"logging": "logging",
"executors": "executors",
+ "extra-links": "extra-links",
+ "queues": "queues",
+ "auth-managers": "auth-managers",
+ "db-managers": "db-managers",
Review Comment:
Ideally an entry here would be useful when it renames something , something like `"secrets-backends": "secrets"`
these 4 entries are no-ops. The input and output are the same string, which is exactly what the fallback produces anyway. Delete those four lines and the behavior will be identical.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Add more provider module categories to the provider page [airflow]
Posted by "kaxil (via GitHub)" <gi...@apache.org>.
kaxil commented on code in PR #70190:
URL: https://github.com/apache/airflow/pull/70190#discussion_r3624368617
##########
dev/registry/registry_tools/types.py:
##########
@@ -109,6 +109,48 @@
"label": "Toolsets",
"icon": "U",
},
+ "extra_link": {
+ "yaml_key": "extra-links",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Extra Links",
+ "icon": "I",
+ },
+ "queue": {
+ "yaml_key": "queues",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Queues",
+ "icon": "Q",
+ },
+ "plugin": {
+ "yaml_key": "plugins",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Plugins",
+ "icon": "P",
+ },
+ "auth_manager": {
+ "yaml_key": "auth-managers",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Auth Managers",
+ "icon": "A",
+ },
+ "db_manager": {
+ "yaml_key": "db-managers",
+ "level": "flat",
+ "suffixes": [],
+ "label": "DB Managers",
+ "icon": "D",
+ },
+ "dialect": {
+ "yaml_key": "dialects",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Dialects",
+ "icon": "C",
+ },
Review Comment:
Queues and dialect feel weird
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Add more provider module categories to the provider page [airflow]
Posted by "Lee-W (via GitHub)" <gi...@apache.org>.
Lee-W commented on code in PR #70190:
URL: https://github.com/apache/airflow/pull/70190#discussion_r3627054316
##########
dev/registry/registry_tools/types.py:
##########
@@ -109,6 +109,48 @@
"label": "Toolsets",
"icon": "U",
},
+ "extra_link": {
+ "yaml_key": "extra-links",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Extra Links",
+ "icon": "I",
+ },
+ "queue": {
+ "yaml_key": "queues",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Queues",
+ "icon": "Q",
+ },
+ "plugin": {
+ "yaml_key": "plugins",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Plugins",
+ "icon": "P",
+ },
+ "auth_manager": {
+ "yaml_key": "auth-managers",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Auth Managers",
+ "icon": "A",
+ },
+ "db_manager": {
+ "yaml_key": "db-managers",
+ "level": "flat",
+ "suffixes": [],
+ "label": "DB Managers",
+ "icon": "D",
+ },
+ "dialect": {
+ "yaml_key": "dialects",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Dialects",
+ "icon": "C",
+ },
Review Comment:
Queues look something like this:
<img width="2576" height="998" alt="image" src="https://github.com/user-attachments/assets/989e031a-799e-4d06-ba66-4ee88a3507a2" />
And dialects look like this:
<img width="2316" height="1206" alt="image" src="https://github.com/user-attachments/assets/10d1c6f5-647f-4cdf-bd4f-228b156b6df2" />
I'm a bit unsure about adding dialects, but I do think we should include queues.
I also considered removing all of these less common fields altogether, but in the end I decided to include them since they don't add much noise and may still be useful for some users.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Add more provider module categories to the provider page [airflow]
Posted by "phanikumv (via GitHub)" <gi...@apache.org>.
phanikumv commented on code in PR #70190:
URL: https://github.com/apache/airflow/pull/70190#discussion_r3629765571
##########
dev/registry/registry_tools/types.py:
##########
@@ -139,11 +181,19 @@
# Class-level sections used by extract_parameters.py (subset of flat that
# list full class paths rather than simple entries).
+#
+# "plugins" and "dialects" are also flat/class-path sections, but each entry is a
+# dict (plugin-class / dialect-class-name) rather than a bare string, so they are
+# handled by their own loops in extract_parameters.py instead of this generic one.
CLASS_LEVEL_SECTIONS: dict[str, str] = {
"notifications": "notifier",
"secrets-backends": "secret",
"logging": "logging",
"executors": "executor",
+ "extra-links": "extra_link",
Review Comment:
`extract_versions.py` doesn't read these `CLASS_LEVEL_SECTIONS` — it has its own hardcoded `FQCN_SECTIONS` (line 304) that still stops at notifications/secrets/logging/executors. So backfilled version pages won't show any of the new categories, only latest pages will. Was that intentional?
It'd be nice if `extract_versions.py` picked these up from here the way it already does with `MODULE_LEVEL_SECTIONS`.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Add more provider module categories to the provider page [airflow]
Posted by "Lee-W (via GitHub)" <gi...@apache.org>.
Lee-W commented on code in PR #70190:
URL: https://github.com/apache/airflow/pull/70190#discussion_r3636258652
##########
dev/registry/registry_tools/types.py:
##########
@@ -109,6 +109,48 @@
"label": "Toolsets",
"icon": "U",
},
+ "extra_link": {
+ "yaml_key": "extra-links",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Extra Links",
+ "icon": "I",
+ },
+ "queue": {
+ "yaml_key": "queues",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Queues",
+ "icon": "Q",
+ },
+ "plugin": {
+ "yaml_key": "plugins",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Plugins",
+ "icon": "P",
+ },
+ "auth_manager": {
+ "yaml_key": "auth-managers",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Auth Managers",
+ "icon": "A",
+ },
+ "db_manager": {
+ "yaml_key": "db-managers",
+ "level": "flat",
+ "suffixes": [],
+ "label": "DB Managers",
+ "icon": "D",
+ },
+ "dialect": {
+ "yaml_key": "dialects",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Dialects",
+ "icon": "C",
+ },
Review Comment:
Just updated it. Thanks!
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Add more provider module categories to the provider page [airflow]
Posted by "Lee-W (via GitHub)" <gi...@apache.org>.
Lee-W merged PR #70190:
URL: https://github.com/apache/airflow/pull/70190
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Add more provider module categories to the provider page [airflow]
Posted by "Lee-W (via GitHub)" <gi...@apache.org>.
Lee-W commented on code in PR #70190:
URL: https://github.com/apache/airflow/pull/70190#discussion_r3713643133
##########
registry/src/_data/types.json:
##########
@@ -63,5 +63,35 @@
"id": "retry_policy",
"label": "Retry Policies",
"icon": "R"
+ },
+ {
+ "id": "extra_link",
+ "label": "Extra Links",
+ "icon": "I"
+ },
+ {
+ "id": "queue",
+ "label": "Message Queues",
+ "icon": "Q"
+ },
+ {
+ "id": "plugin",
+ "label": "Plugins",
+ "icon": "P"
+ },
+ {
+ "id": "auth_manager",
+ "label": "Auth Managers",
+ "icon": "A"
+ },
+ {
+ "id": "db_manager",
+ "label": "DB Managers",
+ "icon": "M"
Review Comment:
Both fixed. A `typeIcon` filter next to `sortTypesByCount` gives the card its curated letter, and the card colour rules now cover all 19 ids instead of 6.
It now shows M for db_mangers
<img width="1648" height="160" alt="image" src="https://github.com/user-attachments/assets/51114f2a-5921-44c7-a7a9-b1218599a8ea" />
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Add more provider module categories to the provider page [airflow]
Posted by "Lee-W (via GitHub)" <gi...@apache.org>.
Lee-W commented on PR #70190:
URL: https://github.com/apache/airflow/pull/70190#issuecomment-5057144623
<img width="3116" height="2068" alt="image" src="https://github.com/user-attachments/assets/8f1c07f4-e452-464a-b693-b241cfd224a5" />
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Add more provider module categories to the provider page [airflow]
Posted by "Lee-W (via GitHub)" <gi...@apache.org>.
Lee-W commented on code in PR #70190:
URL: https://github.com/apache/airflow/pull/70190#discussion_r3713673470
##########
dev/registry/tests/test_types.py:
##########
@@ -93,6 +95,14 @@ def test_class_level_sections_are_subset_of_flat(self):
assert yaml_key in FLAT_LEVEL_SECTIONS
assert FLAT_LEVEL_SECTIONS[yaml_key] == type_id
+ def test_class_level_category_overrides_are_subset_of_class_level_sections(self):
+ assert set(CLASS_LEVEL_CATEGORY_OVERRIDES.keys()) <= set(CLASS_LEVEL_SECTIONS.keys())
+
+ def test_dict_shaped_class_level_sections_are_subset_of_flat(self):
Review Comment:
Added, with `transfers` and `task-decorators` as a named exemption set so the reason they are excluded sits next to the assertion. Dropping a key from `CLASS_LEVEL_SECTIONS` now failed the test.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Add more provider module categories to the provider page [airflow]
Posted by "uranusjr (via GitHub)" <gi...@apache.org>.
uranusjr commented on code in PR #70190:
URL: https://github.com/apache/airflow/pull/70190#discussion_r3689800503
##########
dev/registry/tests/test_extract_parameters.py:
##########
@@ -1086,3 +1157,31 @@ def test_extra_whitespace_is_tolerated(self):
def test_duplicate_providers_collapsed(self):
assert _parse_requested_providers("amazon amazon google") == {"amazon", "google"}
+
+
+class TestResolveDottedPath:
+ @pytest.mark.parametrize(
+ "class_path",
+ (
+ "no_dot_here",
+ "this.module.does.not.exist.at.all.Foo",
+ ),
+ )
+ def test__resolve_dotted_path_returns_none(self, class_path: str):
+ assert _resolve_dotted_path(class_path) is None
+
+ @pytest.mark.parametrize(
+ ("class_path", "expected"),
+ (
+ (
+ "extract_parameters.ThisAttrDoesNotExist",
+ ("extract_parameters", "ThisAttrDoesNotExist", None),
+ ),
+ (
+ "extract_parameters.get_category",
+ ("extract_parameters", "get_category", get_category),
+ ),
+ ),
+ )
+ def test__resolve_dottted_path(self, class_path: str, expected: tuple[str, str, object]):
Review Comment:
```suggestion
def test__resolve_dotted_path(self, class_path: str, expected: tuple[str, str, object]):
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Add more provider module categories to the provider page [airflow]
Posted by "kaxil (via GitHub)" <gi...@apache.org>.
kaxil commented on code in PR #70190:
URL: https://github.com/apache/airflow/pull/70190#discussion_r3624364680
##########
dev/registry/registry_tools/types.py:
##########
@@ -109,6 +109,48 @@
"label": "Toolsets",
"icon": "U",
},
+ "extra_link": {
+ "yaml_key": "extra-links",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Extra Links",
+ "icon": "I",
+ },
+ "queue": {
+ "yaml_key": "queues",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Queues",
+ "icon": "Q",
Review Comment:
What's this?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Add more provider module categories to the provider page [airflow]
Posted by "kaxil (via GitHub)" <gi...@apache.org>.
kaxil commented on code in PR #70190:
URL: https://github.com/apache/airflow/pull/70190#discussion_r3632722949
##########
dev/registry/registry_tools/types.py:
##########
@@ -109,6 +109,48 @@
"label": "Toolsets",
"icon": "U",
},
+ "extra_link": {
+ "yaml_key": "extra-links",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Extra Links",
+ "icon": "I",
+ },
+ "queue": {
+ "yaml_key": "queues",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Queues",
+ "icon": "Q",
+ },
+ "plugin": {
+ "yaml_key": "plugins",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Plugins",
+ "icon": "P",
+ },
+ "auth_manager": {
+ "yaml_key": "auth-managers",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Auth Managers",
+ "icon": "A",
+ },
+ "db_manager": {
+ "yaml_key": "db-managers",
+ "level": "flat",
+ "suffixes": [],
+ "label": "DB Managers",
+ "icon": "D",
+ },
+ "dialect": {
+ "yaml_key": "dialects",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Dialects",
+ "icon": "C",
+ },
Review Comment:
Aah **Message Queues** -- I think we should relabel it to "**Message Queues**" so folks aren't confused with things like "queue" argument on Base Operator.
https://airflow.apache.org/docs/apache-airflow-providers-common-messaging/stable/index.html
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Add more provider module categories to the provider page [airflow]
Posted by "Lee-W (via GitHub)" <gi...@apache.org>.
Lee-W commented on code in PR #70190:
URL: https://github.com/apache/airflow/pull/70190#discussion_r3636684232
##########
dev/registry/registry_tools/types.py:
##########
@@ -139,11 +181,19 @@
# Class-level sections used by extract_parameters.py (subset of flat that
# list full class paths rather than simple entries).
+#
+# "plugins" and "dialects" are also flat/class-path sections, but each entry is a
+# dict (plugin-class / dialect-class-name) rather than a bare string, so they are
+# handled by their own loops in extract_parameters.py instead of this generic one.
CLASS_LEVEL_SECTIONS: dict[str, str] = {
"notifications": "notifier",
"secrets-backends": "secret",
"logging": "logging",
"executors": "executor",
+ "extra-links": "extra_link",
Review Comment:
Thanks for pointing out! It wasn't intentional. `extract_versions.py` now uses `CLASS_LEVEL_SECTIONS` in `types.py` instead of a separate hardcoded list, so backfilled version will show all the same categories . Also moved the category-override rule into a shared `CLASS_LEVEL_CATEGORY_OVERRIDES` constant so `extract_parameters.py` and `extract_versions.py` won't drift again.
##########
registry/src/js/provider-detail.js:
##########
@@ -155,6 +157,44 @@
});
});
+ // "More" overflow menu for module tabs that don't fit in the visible row.
+ var moduleTabMoreBtn = document.getElementById('module-tab-more-btn');
+ var moduleTabMoreMenu = document.getElementById('module-tab-more-menu');
+
+ if (moduleTabMoreBtn && moduleTabMoreMenu) {
+ function closeMoreMenu() {
+ moduleTabMoreBtn.setAttribute('aria-expanded', 'false');
+ moduleTabMoreMenu.hidden = true;
+ }
+
+ moduleTabMoreBtn.addEventListener('click', function(e) {
+ e.stopPropagation();
+ var isOpen = moduleTabMoreBtn.getAttribute('aria-expanded') === 'true';
+ if (isOpen) {
+ closeMoreMenu();
+ } else {
+ moduleTabMoreBtn.setAttribute('aria-expanded', 'true');
+ moduleTabMoreMenu.hidden = false;
+ }
+ });
+
+ document.addEventListener('click', function(e) {
+ if (!moduleTabMoreMenu.contains(e.target) && e.target !== moduleTabMoreBtn) {
+ closeMoreMenu();
+ }
+ });
+
+ document.addEventListener('keydown', function(e) {
+ if (e.key === 'Escape') closeMoreMenu();
+ });
+
+ // Selecting a tab inside the menu also closes it (filtering itself is
+ // handled by the shared moduleTabs click listener above).
+ moduleTabMoreMenu.querySelectorAll('.module-tab').forEach(function(tab) {
+ tab.addEventListener('click', closeMoreMenu);
Review Comment:
"More" button is now `active` while the selected type is in the overflow menu, so it's still visible what the list is filtered by.
##########
registry/src/js/provider-detail.js:
##########
@@ -155,6 +157,44 @@
});
});
+ // "More" overflow menu for module tabs that don't fit in the visible row.
+ var moduleTabMoreBtn = document.getElementById('module-tab-more-btn');
+ var moduleTabMoreMenu = document.getElementById('module-tab-more-menu');
+
+ if (moduleTabMoreBtn && moduleTabMoreMenu) {
+ function closeMoreMenu() {
+ moduleTabMoreBtn.setAttribute('aria-expanded', 'false');
+ moduleTabMoreMenu.hidden = true;
+ }
+
+ moduleTabMoreBtn.addEventListener('click', function(e) {
+ e.stopPropagation();
+ var isOpen = moduleTabMoreBtn.getAttribute('aria-expanded') === 'true';
+ if (isOpen) {
+ closeMoreMenu();
+ } else {
+ moduleTabMoreBtn.setAttribute('aria-expanded', 'true');
+ moduleTabMoreMenu.hidden = false;
+ }
+ });
+
+ document.addEventListener('click', function(e) {
+ if (!moduleTabMoreMenu.contains(e.target) && e.target !== moduleTabMoreBtn) {
+ closeMoreMenu();
+ }
+ });
+
+ document.addEventListener('keydown', function(e) {
+ if (e.key === 'Escape') closeMoreMenu();
Review Comment:
`closeMoreMenu` now returns focus to the trigger when focus was inside the menu. I also dropped `role="menu"` / `role="menuitem"`.
##########
dev/registry/registry_tools/types.py:
##########
@@ -147,11 +189,39 @@
# Class-level sections used by extract_parameters.py (subset of flat that
# list full class paths rather than simple entries).
+#
+# "plugins" and "dialects" are also flat/class-path sections, but each entry is a
+# dict (plugin-class / dialect-class-name) rather than a bare string, and the
+# integration-name field they carry differs between the two, so extract_parameters.py
+# still walks them with their own loops instead of this generic one. The class-path
+# field name itself is shared via DICT_SHAPED_CLASS_LEVEL_SECTIONS below so both
+# extract_versions.py and extract_parameters.py read it from one place.
CLASS_LEVEL_SECTIONS: dict[str, str] = {
"notifications": "notifier",
"secrets-backends": "secret",
"logging": "logging",
"executors": "executor",
+ "extra-links": "extra_link",
+ "queues": "queue",
+ "auth-managers": "auth_manager",
+ "db-managers": "db_manager",
+}
+
+# Maps yaml section key -> (type id, class-path field name) for dict-shaped
+# class-level sections (each yaml entry is a dict, not a bare class-path
+# string), shared by extract_versions.py and extract_parameters.py so the
+# field name is defined exactly once.
+DICT_SHAPED_CLASS_LEVEL_SECTIONS: dict[str, tuple[str, str]] = {
+ "plugins": ("plugin", "plugin-class"),
+ "dialects": ("dialect", "dialect-class-name"),
+}
Review Comment:
sounds good, just updated it
##########
dev/registry/tests/test_extract_parameters.py:
##########
@@ -1086,3 +1157,31 @@ def test_extra_whitespace_is_tolerated(self):
def test_duplicate_providers_collapsed(self):
assert _parse_requested_providers("amazon amazon google") == {"amazon", "google"}
+
+
+class TestResolveDottedPath:
+ @pytest.mark.parametrize(
+ "class_path",
+ (
+ "no_dot_here",
+ "this.module.does.not.exist.at.all.Foo",
+ ),
+ )
+ def test__resolve_dotted_path_returns_none(self, class_path: str):
+ assert _resolve_dotted_path(class_path) is None
+
+ @pytest.mark.parametrize(
+ ("class_path", "expected"),
+ (
+ (
+ "extract_parameters.ThisAttrDoesNotExist",
+ ("extract_parameters", "ThisAttrDoesNotExist", None),
+ ),
+ (
+ "extract_parameters.get_category",
+ ("extract_parameters", "get_category", get_category),
+ ),
+ ),
+ )
+ def test__resolve_dottted_path(self, class_path: str, expected: tuple[str, str, object]):
Review Comment:
fixed
##########
dev/registry/extract_versions.py:
##########
@@ -300,15 +320,13 @@ def process_module(module_path: str, module_type: str, integration: str, categor
if mp:
process_module(mp, "transfer", source, get_category(source))
- # Class-level sections (full class paths, no source file parsing needed)
- FQCN_SECTIONS: dict[str, tuple[str, str, str]] = {
- # yaml_key: (module_type, category, description_suffix)
- "notifications": ("notifier", "notifications", "notifier"),
- "secrets-backends": ("secret", "secrets", "secrets backend"),
- "logging": ("logging", "logging", "log handler"),
- "executors": ("executor", "executors", "executor"),
- }
- for yaml_key, (mod_type, category, desc_suffix) in FQCN_SECTIONS.items():
+ # Class-level sections (full class paths, no source file parsing needed).
+ # Iterating CLASS_LEVEL_SECTIONS keeps this in sync with the single
+ # source of truth in types.py; a section added there without a matching
+ # FQCN_DESC_SUFFIXES entry raises KeyError instead of silently skipping.
+ for yaml_key, mod_type in CLASS_LEVEL_SECTIONS.items():
Review Comment:
`extract_versions.py` now walks `DICT_SHAPED_CLASS_LEVEL_SECTIONS` alongside `CLASS_LEVEL_SECTIONS`, so plugins and dialects show up on backfilled version pages as well.
The test is parametrized over that dict as well, so a new dict-shaped section will be covered.
##########
registry/src/_data/types.json:
##########
@@ -58,5 +58,35 @@
"id": "toolset",
"label": "Toolsets",
"icon": "U"
+ },
+ {
+ "id": "extra_link",
Review Comment:
Added the missing `.type-icon`, `.share-bar` and `.provider-card .modules` rules for the new ids, plus `toolset` and `retry_policy` which had the same gap. They use `rgb(from var(--color-X) r g b / 0.2)` like the existing `.tab-icon` block rather than hardcoded colours.
##########
dev/registry/registry_tools/types.py:
##########
@@ -139,11 +181,27 @@
# Class-level sections used by extract_parameters.py (subset of flat that
# list full class paths rather than simple entries).
+#
+# "plugins" and "dialects" are also flat/class-path sections, but each entry is a
+# dict (plugin-class / dialect-class-name) rather than a bare string, so they are
+# handled by their own loops in extract_parameters.py instead of this generic one.
CLASS_LEVEL_SECTIONS: dict[str, str] = {
"notifications": "notifier",
"secrets-backends": "secret",
"logging": "logging",
"executors": "executor",
+ "extra-links": "extra_link",
+ "queues": "queue",
Review Comment:
Yep, will create a follow up PR for this.
##########
dev/registry/registry_tools/types.py:
##########
@@ -116,6 +116,48 @@
"label": "Retry Policies",
"icon": "R",
},
+ "extra_link": {
+ "yaml_key": "extra-links",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Extra Links",
+ "icon": "I",
+ },
+ "queue": {
+ "yaml_key": "queues",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Message Queues",
+ "icon": "Q",
+ },
+ "plugin": {
+ "yaml_key": "plugins",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Plugins",
+ "icon": "P",
+ },
+ "auth_manager": {
+ "yaml_key": "auth-managers",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Auth Managers",
+ "icon": "A",
+ },
+ "db_manager": {
+ "yaml_key": "db-managers",
+ "level": "flat",
+ "suffixes": [],
+ "label": "DB Managers",
+ "icon": "D",
+ },
+ "dialect": {
+ "yaml_key": "dialects",
+ "level": "flat",
+ "suffixes": [],
+ "label": "Dialects",
+ "icon": "C",
Review Comment:
Making
* `dialect` -> `D`
* `db_manager` -> `M`
so `C` is left for connection.
Thought of whether we have better combinations, but this seems to be the best we can get
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@airflow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org