|
26 | 26 | import logging |
27 | 27 | import traceback |
28 | 28 | import warnings |
29 | | -from collections.abc import Callable, MutableMapping |
| 29 | +from collections.abc import Callable, Iterator, MutableMapping |
30 | 30 | from dataclasses import dataclass |
31 | 31 | from functools import wraps |
32 | 32 | from importlib.resources import files as resource_files |
@@ -243,6 +243,15 @@ class HookInfo(NamedTuple): |
243 | 243 | dialects: list[str] = [] |
244 | 244 |
|
245 | 245 |
|
| 246 | +class ConnectionTypeHookUIMetadata(NamedTuple): |
| 247 | + """Hook metadata for one connection type (connection UI); ``field_behaviour`` is standard fields.""" |
| 248 | + |
| 249 | + connection_type: str |
| 250 | + hook_name: str |
| 251 | + hook_class_name: str | None |
| 252 | + field_behaviour: dict | None |
| 253 | + |
| 254 | + |
246 | 255 | class ConnectionFormWidgetInfo(NamedTuple): |
247 | 256 | """Connection Form Widget information.""" |
248 | 257 |
|
@@ -413,6 +422,8 @@ def __init__(self): |
413 | 422 | self._dialect_provider_dict: dict[str, DialectInfo] = {} |
414 | 423 | # Keeps dict of hooks keyed by connection type. They are lazy evaluated at access time |
415 | 424 | self._hooks_lazy_dict: LazyDictWithCache[str, HookInfo | Callable] = LazyDictWithCache() |
| 425 | + # Keeps hook display names read from provider.yaml (hook-name field) |
| 426 | + self._hook_name_dict: dict[str, str] = {} |
416 | 427 | # Keeps methods that should be used to add custom widgets tuple of keyed by name of the extra field |
417 | 428 | self._connection_form_widgets: dict[str, ConnectionFormWidgetInfo] = {} |
418 | 429 | # Customizations for javascript fields are kept here |
@@ -979,6 +990,9 @@ def _load_ui_metadata(self) -> None: |
979 | 990 | if not connection_type or not hook_class_name: |
980 | 991 | continue |
981 | 992 |
|
| 993 | + if hook_name := conn_config.get("hook-name"): |
| 994 | + self._hook_name_dict[connection_type] = hook_name |
| 995 | + |
982 | 996 | if conn_fields := conn_config.get("conn-fields"): |
983 | 997 | self._add_widgets(package_name, hook_class_name, connection_type, conn_fields) |
984 | 998 |
|
@@ -1349,6 +1363,45 @@ def hooks(self) -> MutableMapping[str, HookInfo | None]: |
1349 | 1363 | # When we return hooks here it will only be used to retrieve hook information |
1350 | 1364 | return self._hooks_lazy_dict |
1351 | 1365 |
|
| 1366 | + def iter_connection_type_hook_ui_metadata(self) -> Iterator[ConnectionTypeHookUIMetadata]: |
| 1367 | + """ |
| 1368 | + Yield hook metadata per connection type for the connection UI. |
| 1369 | +
|
| 1370 | + Does not import hook classes. |
| 1371 | + """ |
| 1372 | + self.initialize_providers_hooks() |
| 1373 | + all_types = frozenset(self._hooks_lazy_dict) | frozenset(self._hook_provider_dict) |
| 1374 | + for conn_type in sorted(all_types): |
| 1375 | + raw_entry = self._hooks_lazy_dict._raw_dict.get(conn_type) |
| 1376 | + provider_entry = self._hook_provider_dict.get(conn_type) |
| 1377 | + if isinstance(raw_entry, HookInfo): |
| 1378 | + hook_name = raw_entry.hook_name |
| 1379 | + hook_class_name = raw_entry.hook_class_name |
| 1380 | + elif provider_entry: |
| 1381 | + hook_name = self._hook_name_dict.get(conn_type, conn_type) |
| 1382 | + hook_class_name = provider_entry.hook_class_name |
| 1383 | + else: |
| 1384 | + hook_name = self._hook_name_dict.get(conn_type, conn_type) |
| 1385 | + hook_class_name = None |
| 1386 | + yield ConnectionTypeHookUIMetadata( |
| 1387 | + connection_type=conn_type, |
| 1388 | + hook_name=hook_name, |
| 1389 | + hook_class_name=hook_class_name, |
| 1390 | + field_behaviour=self._field_behaviours.get(conn_type), |
| 1391 | + ) |
| 1392 | + |
| 1393 | + @property |
| 1394 | + def _connection_form_widgets_from_metadata(self) -> dict[str, ConnectionFormWidgetInfo]: |
| 1395 | + """Return connection form widgets from metadata without importing every hook.""" |
| 1396 | + self.initialize_providers_hooks() |
| 1397 | + return self._connection_form_widgets |
| 1398 | + |
| 1399 | + @property |
| 1400 | + def _field_behaviours_from_metadata(self) -> dict[str, dict]: |
| 1401 | + """Return field behaviour dicts from metadata without importing every hook.""" |
| 1402 | + self.initialize_providers_hooks() |
| 1403 | + return self._field_behaviours |
| 1404 | + |
1352 | 1405 | @property |
1353 | 1406 | def dialects(self) -> MutableMapping[str, DialectInfo]: |
1354 | 1407 | """Return dictionary of connection_type-to-dialect mapping.""" |
|
0 commit comments