jedcunningham commented on a change in pull request #15385:
URL: https://github.com/apache/airflow/pull/15385#discussion_r688641009
##########
File path: tests/www/views/test_views.py
##########
@@ -93,6 +95,28 @@ def test_plugin_endpoint_should_not_be_unauthenticated(app):
check_content_in_response("Sign In - Airflow", resp)
+def test_should_list_providers_on_page_with_details(admin_client):
+ pm = ProvidersManager()
+ resp = admin_client.get('/provider')
+
+ for pi in pm.providers.values():
+ check_content_in_response("<td>" + pi.version + "</td>", resp)
+ check_content_in_response("<td>" + pi[1]["package-name"] + "</td>",
resp)
+ cd = re.sub(
+ ">",
+ "\">[site]</a>",
+ re.sub("<", "<a href=\"", re.sub("[`_]", "",
pi[1]["description"].strip(" \n.").strip("\""))),
+ )
Review comment:
I'm thinking instead of duplicating this logic, maybe we test a specific
providers stuff is built properly with static values here? Thoughts?
##########
File path: airflow/www/views.py
##########
@@ -3339,6 +3339,58 @@ def list(self):
)
+class ProviderView(AirflowBaseView):
+ """View to show Airflow Providers"""
+
+ default_view = 'list'
+
+ class_permission_name = permissions.RESOURCE_PROVIDER
+
+ method_permission_name = {
+ 'list': 'read',
+ }
+
+ base_permissions = [
+ permissions.ACTION_CAN_READ,
+ permissions.ACTION_CAN_ACCESS_MENU,
+ ]
+
+ @expose('/provider')
+ @auth.has_access(
+ [
+ (permissions.ACTION_CAN_READ, permissions.RESOURCE_PROVIDER),
+ ]
+ )
+ def list(self):
+ """List providers."""
+ providers_manager = ProvidersManager()
+
+ providers = []
+ for pi in providers_manager.providers.values():
+ provider_info = pi[1]
+ provider_data = {
+ "package_name": provider_info["package-name"],
+ "description":
self._clean_description(provider_info["description"]),
+ "version": pi[0],
+ }
+ providers.append(provider_data)
+
+ title = "Providers"
+ doc_url = get_docs_url("apache-airflow-providers/index.html")
+ return self.render_template(
+ 'airflow/providers.html',
+ providers=providers,
+ title=title,
+ doc_url=doc_url,
+ )
+
+ def _clean_description(self, description):
+ cd = re.sub("[`_]", "", description.strip(" \n.").strip("\""))
+ cd = re.sub("<", "<a href=\"", cd)
+ cd = re.sub(">", "\">[site]</a>", cd)
+ return cd
Review comment:
```suggestion
import markupsafe # Should be moved to the top of the file
def _build_link(matchobj):
# These were already escaped, so we can use them as-is
text = matchobj.group(1)
url = matchobj.group(2)
return markupsafe.Markup(f'<a href="{url}">{text}</a>')
safe = markupsafe.escape(description)
safe = re.sub(r"`(.*) +<(.*)>`__", _build_link, safe)
safe = re.sub(r"\n", r"<br>", safe)
return markupsafe.Markup(safe)
```
This will allow you to remove the `safe` filter, plus I think it renders the
links more nicely, e.g:


--
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: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]