amoghrajesh commented on code in PR #60410:
URL: https://github.com/apache/airflow/pull/60410#discussion_r2741232816
##########
airflow-core/src/airflow/providers_manager.py:
##########
@@ -926,6 +927,136 @@ def _get_attr(obj: Any, attr_name: str):
return None
return getattr(obj, attr_name)
+ def _get_connection_type_config_from_yaml(
+ self, provider_info: ProviderInfo, connection_type: str
+ ) -> dict | None:
+ """Get connection type config from provider.yaml if it exists."""
+ connection_types = provider_info.data.get("connection-types", [])
+ for conn_config in connection_types:
+ if conn_config.get("connection-type") == connection_type:
+ return conn_config
+ return None
+
+ @staticmethod
+ def _get_mock_field_for_field_type(field_type, field_format):
+ from airflow.api_fastapi.core_api.services.ui.connections import
HookMetaService
+
+ field_type_to_mock_field_map = {
+ ("string", "password"): HookMetaService.MockPasswordField,
+ ("string", None): HookMetaService.MockStringField,
+ ("integer", None): HookMetaService.MockIntegerField,
+ ("boolean", None): HookMetaService.MockBooleanField,
+ ("number", None): HookMetaService.MockIntegerField,
+ }
+
+ field_class = field_type_to_mock_field_map.get((field_type,
field_format))
+
+ return field_class
+
+ def _create_field_from_yaml(self, field_name: str, field_def: dict) -> Any:
+ """Build mock field from yaml conn-fields definition."""
+ from airflow.api_fastapi.core_api.services.ui.connections import
HookMetaService
+
+ label = field_def.get("label")
+ description = field_def.get("description")
+ schema = field_def.get("schema", {})
+ field_type = schema.get("type")
+ if isinstance(field_type, list):
+ field_type = next((t for t in field_type if t != "null"), "string")
+
+ field_class =
ProvidersManager._get_mock_field_for_field_type(field_type,
schema.get("format"))
+ if not field_class:
+ log.warning("Unknown field type '%s' for field '%s' in
conn-fields", field_type, field_name)
+ return None
+
+ validators = []
+ if "enum" in schema:
+ validators.append(HookMetaService.MockEnum(schema["enum"]))
+ if (
+ isinstance(schema.get("type"), list)
+ and "null" in schema["type"]
+ or not field_def.get("required", False)
+ ):
+ validators.append(HookMetaService.MockOptional())
+
+ return field_class(
+ label=label,
+ description=description,
+ default=schema.get("default"),
+ validators=validators if validators else None,
+ )
+
+ def _add_widgets_from_yaml(
+ self, package_name: str, hook_class_name: str, connection_type: str,
conn_fields_yaml: dict
+ ) -> None:
+ """Parse conn-fields from yaml and add to connection_form_widgets."""
+ for field_name, field_def in conn_fields_yaml.items():
+ field = self._create_field_from_yaml(field_name, field_def)
+ if field is None:
+ continue
+
+ prefixed_name = f"extra__{connection_type}__{field_name}"
+ if prefixed_name in self._connection_form_widgets:
+ log.warning(
+ "Field %s for connection type %s already added, skipping",
+ field_name,
+ connection_type,
+ )
+ continue
+
+ self._connection_form_widgets[prefixed_name] =
ConnectionFormWidgetInfo(
+ hook_class_name=hook_class_name,
+ package_name=package_name,
+ field=field,
+ field_name=field_name,
+ is_sensitive=field_def.get("sensitive", False),
+ )
Review Comment:
Totally valid concern. This was done just to ensure unified code path. The
current flow looks like this:
1. For yaml path, `_load_ui_metadata_from_yaml` -> `_create_field_from_yaml`
- This path reads the `conn-fields` from yaml
- Creates the `MockBaseField` objects
- STores those in `_connection_form_widgets`
2. For those where first path doesn't work, `_import_hook` path is chosen
- Imports the hook class
- Calls `get_connectoion_form_widgets`
- Creates `MockBaseField` objects
- Stores in `_connection_form_widgets`
My thought here was to keep the code kind of unified. ie: Since both paths
converge on `MockBaseField` -> `SerializedParam`, and is later served by API, i
kept it simple here. But yeah, I can do some changes.
I think we can skip the `MockBaseField` crreation for yaml path and serve it
via API without conversion, might require some API changes but its ok.
--
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]