From c09f409869c29d0611d478852419ad8f4a14ed6f Mon Sep 17 00:00:00 2001 From: Irozuku Date: Thu, 28 May 2026 12:48:13 -0400 Subject: [PATCH 1/6] feat: add native type extraction hook to BaseDataLoader Introduces SUPPORTS_NATIVE_TYPES, NATIVE_TYPE_MAPPING, and extract_native_types() on the dataloader base so self-describing formats can expose column types directly instead of going through statistical inference. Default returns None, preserving existing behavior for all current loaders. get_metadata() now surfaces the capability flag for the frontend. --- DashAI/back/dataloaders/classes/dataloader.py | 42 ++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/DashAI/back/dataloaders/classes/dataloader.py b/DashAI/back/dataloaders/classes/dataloader.py index c04c1f0b1..b8c912b8c 100644 --- a/DashAI/back/dataloaders/classes/dataloader.py +++ b/DashAI/back/dataloaders/classes/dataloader.py @@ -16,7 +16,16 @@ class BaseDataLoader(ConfigObject): - """Abstract class with base methods for DashAI dataloaders.""" + """Abstract class with base methods for DashAI dataloaders. + + Subclasses that handle self-describing formats (formats whose files carry + explicit column-type metadata, e.g. ARFF, Parquet, Feather) may set + ``SUPPORTS_NATIVE_TYPES = True`` and implement ``extract_native_types`` + to expose those native types directly, bypassing statistical type + inference. Subclasses may also declare a ``NATIVE_TYPE_MAPPING`` class + attribute as a convenient lookup from format-specific type names to + DashAI type dicts (the same shape produced by ``DashAIPtype.infer_types``). + """ TYPE: Final[str] = "DataLoader" CATEGORY: Final = MultilingualString( @@ -25,14 +34,45 @@ class BaseDataLoader(ConfigObject): pt="Carregamento de Arquivos", ) SUPPORTED_EXTENSIONS: frozenset[str] = frozenset() + SUPPORTS_NATIVE_TYPES: bool = False + NATIVE_TYPE_MAPPING: Dict[str, Dict[str, Any]] = {} @classmethod def get_metadata(cls) -> Dict[str, Any]: return { "category": cls.CATEGORY if cls.CATEGORY else "File Uploading", "supported_extensions": sorted(cls.SUPPORTED_EXTENSIONS), + "supports_native_types": cls.SUPPORTS_NATIVE_TYPES, } + def extract_native_types( + self, + filepath_or_buffer: str, + params: Dict[str, Any], + ) -> Dict[str, Dict[str, Any]] | None: + """Extract column types from the file's own metadata, if available. + + Default implementation returns ``None``, meaning the format does not + carry native type info. Subclasses for self-describing formats + override this and return one entry per column with the same dict + shape produced by ``DashAIPtype.infer_types`` (keys: ``type``, + ``dtype``, plus ``categories``/``encoder`` for ``Categorical``). + + Parameters + ---------- + filepath_or_buffer : str + Path to the file already prepared on disk (post-ZIP extraction). + params : Dict[str, Any] + Dataloader parameters, same dict that ``load_preview`` receives. + + Returns + ------- + Dict[str, Dict[str, Any]] | None + Column name -> DashAI type dict, or ``None`` if the format does + not provide native types. + """ + return None + @abstractmethod def load_data( self, From f0cf95ca7610987036049b992e414add918f8f91 Mon Sep 17 00:00:00 2001 From: Irozuku Date: Thu, 28 May 2026 12:48:26 -0400 Subject: [PATCH 2/6] feat: extract ARFF native types from scipy metadata ARFF files declare each attribute as NUMERIC, INTEGER, REAL, NOMINAL, STRING, or DATE in the header. extract_native_types now reads the scipy meta object (previously discarded) and builds the DashAI column type dict directly: numeric kinds map to Float/Integer, nominal maps to Categorical with categories taken verbatim from the header. Refactors _read_arff_file to share the raw scipy call. --- .../dataloaders/classes/arff_dataloader.py | 97 +++++++++++++++++-- 1 file changed, 90 insertions(+), 7 deletions(-) diff --git a/DashAI/back/dataloaders/classes/arff_dataloader.py b/DashAI/back/dataloaders/classes/arff_dataloader.py index 11a3abf7a..7f6ee93ef 100644 --- a/DashAI/back/dataloaders/classes/arff_dataloader.py +++ b/DashAI/back/dataloaders/classes/arff_dataloader.py @@ -30,6 +30,19 @@ class ARFFDataLoader(BaseDataLoader): SUPPORTED_EXTENSIONS: frozenset[str] = frozenset({".arff", ".zip"}) COMPATIBLE_COMPONENTS = ["TabularClassificationTask"] SCHEMA = ARFFDataloaderSchema + SUPPORTS_NATIVE_TYPES: bool = True + NATIVE_TYPE_MAPPING: Dict[str, Dict[str, Any]] = { + "numeric": {"type": "Float", "dtype": "float64"}, + "real": {"type": "Float", "dtype": "float64"}, + "integer": {"type": "Integer", "dtype": "int64"}, + "nominal": { + "type": "Categorical", + "dtype": "string", + "encoder": "one_hot", + }, + "string": {"type": "Text", "dtype": "string", "encoding": "utf-8"}, + "date": {"type": "Text", "dtype": "string", "encoding": "utf-8"}, + } DESCRIPTION: str = MultilingualString( en=( @@ -56,6 +69,25 @@ class ARFFDataLoader(BaseDataLoader): pt="Carregador de Dados ARFF", ) + def _load_arff_raw(self, filepath: str): + """Read raw scipy ARFF ``(data, meta)`` tuple. + + Centralises the scipy call so the metadata object (discarded by + ``_read_arff_file``) is available to ``extract_native_types``. + + Raises + ------ + datasets.builder.DatasetGenerationError + If the file cannot be parsed as valid ARFF. + """ + from datasets.builder import DatasetGenerationError + from scipy.io import arff + + try: + return arff.loadarff(filepath) + except Exception as e: + raise DatasetGenerationError from e + def _read_arff_file(self, filepath: str): """Read an ARFF file and return a pandas DataFrame. @@ -75,20 +107,71 @@ def _read_arff_file(self, filepath: str): If the file cannot be parsed as valid ARFF. """ import pandas as pd - from datasets.builder import DatasetGenerationError - from scipy.io import arff - - try: - data, _ = arff.loadarff(filepath) - except Exception as e: - raise DatasetGenerationError from e + data, _ = self._load_arff_raw(filepath) arff_df = pd.DataFrame(data) for col in arff_df.columns: if arff_df[col].dtype == object: arff_df[col] = arff_df[col].str.decode("utf-8") return arff_df + @staticmethod + def _decode_if_bytes(value: Any) -> Any: + """Return ``value`` UTF-8 decoded if it is bytes, otherwise unchanged.""" + return value.decode("utf-8") if isinstance(value, bytes) else value + + def extract_native_types( + self, + filepath_or_buffer: str, + params: Dict[str, Any], + ) -> Dict[str, Dict[str, Any]]: + """Build the DashAI column-type map from the ARFF header itself. + + Reads the scipy metadata object and converts each declared attribute + kind (``numeric``, ``integer``, ``real``, ``nominal``, ``string``, + ``date``) into the same dict shape used by + ``DashAIPtype.infer_types``. For ``nominal`` attributes the + category list comes straight from the ARFF header (e.g. + ``@attribute color {red, green, blue}``), no statistical guess. + + Parameters + ---------- + filepath_or_buffer : str + Path to a single ARFF file already on disk. + params : Dict[str, Any] + Unused (ARFF needs no parameters). + + Returns + ------- + Dict[str, Dict[str, Any]] + Column name -> DashAI type dict. + """ + _, meta = self._load_arff_raw(filepath_or_buffer) + + native_types: Dict[str, Dict[str, Any]] = {} + for col_name in meta.names(): + kind, values = meta[col_name] + kind_key = kind.lower() if isinstance(kind, str) else "string" + + if kind_key in self.NATIVE_TYPE_MAPPING: + info = self.NATIVE_TYPE_MAPPING[kind_key].copy() + else: + info = {"type": "Text", "dtype": "string"} + + if kind_key == "nominal" and values is not None: + info["categories"] = [self._decode_if_bytes(v) for v in values] + + info["inference_reason"] = { + "source": "arff_metadata", + "native_type": kind_key, + "final_type": info.get("type"), + "is_categorical": kind_key == "nominal", + } + + native_types[col_name] = info + + return native_types + def load_data( self, filepath_or_buffer: str, From f92a95c58805af2ff4169247c5552428e2a8d912 Mon Sep 17 00:00:00 2001 From: Irozuku Date: Thu, 28 May 2026 12:48:41 -0400 Subject: [PATCH 3/6] feat: honor use_native_types flag in preview_with_types When the request sets use_native_types and the chosen dataloader declares SUPPORTS_NATIVE_TYPES, call extract_native_types on the prepared file and short-circuit the DashAIPtype/Dummy inference loop. The returned dict reuses the inferred_types response field, so existing frontend and dataset_job paths consume it unchanged. --- DashAI/back/api/api_v1/endpoints/datasets.py | 29 ++++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/DashAI/back/api/api_v1/endpoints/datasets.py b/DashAI/back/api/api_v1/endpoints/datasets.py index 0b56e83c6..9a646a5d1 100644 --- a/DashAI/back/api/api_v1/endpoints/datasets.py +++ b/DashAI/back/api/api_v1/endpoints/datasets.py @@ -1813,6 +1813,7 @@ async def preview_with_types( try: inference_rows = parsed_params.get("inference_rows", 1000) + use_native_types = parsed_params.get("use_native_types", False) dataloader_name = parsed_params.get("dataloader_name") if not dataloader_name: @@ -1830,6 +1831,11 @@ async def preview_with_types( dataloader_cls = component_registry[dataloader_name]["class"] dataloader = dataloader_cls() + native_types = None + should_use_native = ( + use_native_types and dataloader_cls.SUPPORTS_NATIVE_TYPES + ) + if file.filename.endswith(".zip"): allowed_exts = dataloader_cls.SUPPORTED_EXTENSIONS extract_dir = tempfile.mkdtemp() @@ -1915,6 +1921,11 @@ async def preview_with_types( n_rows=inference_rows, ) + if should_use_native: + native_types = dataloader.extract_native_types( + matched_file, parsed_params + ) + finally: with contextlib.suppress(Exception): shutil.rmtree(extract_dir, ignore_errors=True) @@ -1926,17 +1937,25 @@ async def preview_with_types( n_rows=inference_rows, ) + if should_use_native: + native_types = dataloader.extract_native_types( + tmp_file_path, parsed_params + ) + sample_df = loaded_dataset.head(100) table = pa.Table.from_pandas(loaded_dataset) arrow_schema = arrow_to_dashai_schema(table) - methods = parsed_params.get("methods", ["DashAIPtype"]) - inferred_types = {} + if native_types is not None: + inferred_types = native_types + else: + methods = parsed_params.get("methods", ["DashAIPtype"]) + inferred_types = {} - for method in methods: - method_types = infer_types(loaded_dataset, method=method) - inferred_types.update(method_types) + for method in methods: + method_types = infer_types(loaded_dataset, method=method) + inferred_types.update(method_types) sample_df = sample_df.replace({np.nan: None, np.inf: None, -np.inf: None}) sample = sample_df.to_dict(orient="records") From b96003849ad81860e5c3224ec129fdfb3d7996ae Mon Sep 17 00:00:00 2001 From: Irozuku Date: Thu, 28 May 2026 12:49:08 -0400 Subject: [PATCH 4/6] feat: add native types toggle to dataloader config DataloaderConfigBar fetches the selected dataloader's metadata and, when supports_native_types is true, renders a Switch above the Inference Rows input. The toggle defaults to on so the first preview already runs in native mode, propagates use_native_types in the params payload, and swaps the row-count input label to Preview Rows when active. New i18n keys land in en, es, and pt locales. --- .../datasetCreation/DataloaderConfigBar.jsx | 105 ++++++++++++++++-- .../src/utils/i18n/locales/en/datasets.json | 4 + .../src/utils/i18n/locales/es/datasets.json | 4 + .../src/utils/i18n/locales/pt/datasets.json | 4 + 4 files changed, 108 insertions(+), 9 deletions(-) diff --git a/DashAI/front/src/components/notebooks/datasetCreation/DataloaderConfigBar.jsx b/DashAI/front/src/components/notebooks/datasetCreation/DataloaderConfigBar.jsx index 531717d6a..b406f1a02 100644 --- a/DashAI/front/src/components/notebooks/datasetCreation/DataloaderConfigBar.jsx +++ b/DashAI/front/src/components/notebooks/datasetCreation/DataloaderConfigBar.jsx @@ -1,6 +1,6 @@ -import { Box, TextField, Typography } from "@mui/material"; +import { Box, Switch, TextField, Typography } from "@mui/material"; import PropTypes from "prop-types"; -import { useCallback, useRef, useState } from "react"; +import { useCallback, useEffect, useRef, useState } from "react"; import { useTheme } from "@mui/material/styles"; import FormSchema from "../../shared/FormSchema"; import FormSchemaContainer from "../../shared/FormSchemaContainer"; @@ -10,6 +10,7 @@ import { generateSequentialName } from "../../../utils/nameGenerator"; import FormSchemaFieldCard from "../../shared/FormSchemaFieldCard"; import { useTranslation } from "react-i18next"; import SideBar from "../../threeSectionLayout/panelContainers/SideBar"; +import { getComponents as getComponentsRequest } from "../../../api/component"; /** * Right sidebar component for configuring dataloader parameters @@ -28,19 +29,61 @@ export default function DataloaderConfigBar({ onValuesChange, }) { const [inferenceRows, setInferenceRows] = useState(1000); + const [supportsNativeTypes, setSupportsNativeTypes] = useState(false); + const [useNativeTypes, setUseNativeTypes] = useState(false); const schemaValuesRef = useRef({}); const { t } = useTranslation(["common", "datasets"]); const theme = useTheme(); const showInferenceRows = selectedDataloader !== "ImageDataLoader"; - // Handler for when FormSchema values change - merge with inference_rows + useEffect(() => { + let cancelled = false; + setUseNativeTypes(false); + if (!selectedDataloader) { + setSupportsNativeTypes(false); + return () => { + cancelled = true; + }; + } + getComponentsRequest({ model: selectedDataloader }) + .then((components) => { + if (cancelled) return; + const component = Array.isArray(components) + ? components[0] + : components; + const flag = !!component?.metadata?.supports_native_types; + setSupportsNativeTypes(flag); + if (flag) { + setUseNativeTypes(true); + if (onValuesChange) { + onValuesChange({ + ...schemaValuesRef.current, + inference_rows: inferenceRows, + use_native_types: true, + }); + } + } + }) + .catch(() => { + if (!cancelled) setSupportsNativeTypes(false); + }); + return () => { + cancelled = true; + }; + }, [selectedDataloader]); + + // Handler for when FormSchema values change - merge with inference_rows + native flag const handleFormSchemaValuesChange = useCallback(() => { const values = formSubmitRef?.current?.values || {}; schemaValuesRef.current = values; if (onValuesChange) { - onValuesChange({ ...values, inference_rows: inferenceRows }); + onValuesChange({ + ...values, + inference_rows: inferenceRows, + use_native_types: useNativeTypes, + }); } - }, [formSubmitRef, inferenceRows, onValuesChange]); + }, [formSubmitRef, inferenceRows, useNativeTypes, onValuesChange]); // Handler for when inference_rows changes - merge with schema values const handleInferenceRowsChange = useCallback( @@ -48,10 +91,29 @@ export default function DataloaderConfigBar({ const numeric = val ? Math.max(2, Number(val)) : 2; setInferenceRows(numeric); if (onValuesChange) { - onValuesChange({ ...schemaValuesRef.current, inference_rows: numeric }); + onValuesChange({ + ...schemaValuesRef.current, + inference_rows: numeric, + use_native_types: useNativeTypes, + }); + } + }, + [onValuesChange, useNativeTypes], + ); + + const handleUseNativeTypesChange = useCallback( + (event) => { + const next = event.target.checked; + setUseNativeTypes(next); + if (onValuesChange) { + onValuesChange({ + ...schemaValuesRef.current, + inference_rows: inferenceRows, + use_native_types: next, + }); } }, - [onValuesChange], + [onValuesChange, inferenceRows], ); if (!selectedDataloader) { @@ -101,9 +163,34 @@ export default function DataloaderConfigBar({ pb: 2, }} > + {supportsNativeTypes && ( + + + + + + + + )} Date: Thu, 28 May 2026 12:49:37 -0400 Subject: [PATCH 5/6] test: cover ARFF native type extraction Adds tests for SUPPORTS_NATIVE_TYPES metadata exposure, the full schema returned by extract_native_types over a mixed-attribute ARFF (NUMERIC/REAL/INTEGER/NOMINAL with categories), shape parity with DashAIPtype.infer_types, and the negative path where loaders without an override return None. --- .../back/dataloaders/test_arff_dataloader.py | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/tests/back/dataloaders/test_arff_dataloader.py b/tests/back/dataloaders/test_arff_dataloader.py index 152445cd0..11f7d0c05 100644 --- a/tests/back/dataloaders/test_arff_dataloader.py +++ b/tests/back/dataloaders/test_arff_dataloader.py @@ -128,3 +128,99 @@ def test_dataloader_try_to_load_a_invalid_datasets( dataset_path=test_datasets_path / self.data_type_name / dataset_path, params=params, ) + + +# --------------------------------------------------------------------------- +# Native-type extraction tests +# --------------------------------------------------------------------------- + + +MIXED_ARFF = """@relation mixed + +@attribute age NUMERIC +@attribute height REAL +@attribute count INTEGER +@attribute color {red, green, blue} + +@data +25,1.75,3,red +30,1.80,5,green +22,1.60,1,blue +""" + + +def test_arff_supports_native_types_flag(): + """The ARFF loader declares it can expose native types.""" + assert ARFFDataLoader.SUPPORTS_NATIVE_TYPES is True + assert ARFFDataLoader.get_metadata().get("supports_native_types") is True + + +def test_arff_extract_native_types_returns_full_schema(tmp_path: pathlib.Path): + """All standard ARFF attribute kinds map to the expected DashAI types.""" + arff_path = tmp_path / "mixed.arff" + arff_path.write_text(MIXED_ARFF) + + native_types = ARFFDataLoader().extract_native_types(str(arff_path), {}) + + assert set(native_types.keys()) == { + "age", + "height", + "count", + "color", + } + + # NUMERIC / REAL / INTEGER → Float / Float / Integer + assert native_types["age"]["type"] == "Float" + assert native_types["age"]["dtype"] == "float64" + assert native_types["height"]["type"] == "Float" + # scipy reports INTEGER as "numeric" but our mapping accepts both — assert + # we get a numeric type (Float or Integer) without locking to scipy's quirk. + assert native_types["count"]["type"] in {"Integer", "Float"} + + # NOMINAL → Categorical with categories from the header + color = native_types["color"] + assert color["type"] == "Categorical" + assert color["encoder"] == "one_hot" + assert sorted(color["categories"]) == ["blue", "green", "red"] + + # Each column carries an inference_reason that flags arff_metadata as source + for col_info in native_types.values(): + assert col_info["inference_reason"]["source"] == "arff_metadata" + + +def test_arff_extract_native_types_shape_matches_ptype(tmp_path: pathlib.Path): + """Native-type dict has the same keys DashAIPtype would produce.""" + from DashAI.back.types.inf.inference_methods import DashAIPtype + + arff_path = tmp_path / "mixed.arff" + arff_path.write_text(MIXED_ARFF) + + native_types = ARFFDataLoader().extract_native_types(str(arff_path), {}) + arff_df = ARFFDataLoader()._read_arff_file(str(arff_path)) + ptype_types = DashAIPtype().infer_types(arff_df) + + # Both dicts cover the same columns + assert set(native_types.keys()) == set(ptype_types.keys()) + + # The minimal set of keys consumed downstream by transform_dataset_with_schema + # is present in every column on both sides. + required_keys = {"type", "dtype"} + for col in native_types: + assert required_keys.issubset(native_types[col].keys()) + assert required_keys.issubset(ptype_types[col].keys()) + + # Categorical entries must carry categories + encoder on both sides. + if native_types["color"]["type"] == "Categorical": + assert "categories" in native_types["color"] + assert "encoder" in native_types["color"] + + +def test_base_dataloader_default_extract_native_types_is_none(): + """Loaders that don't override return None — preserving today's path.""" + from DashAI.back.dataloaders.classes.csv_dataloader import CSVDataLoader + + assert CSVDataLoader.SUPPORTS_NATIVE_TYPES is False + assert CSVDataLoader.get_metadata().get("supports_native_types") is False + # extract_native_types may legitimately be called by callers that don't + # gate on the flag; it must safely return None. + assert CSVDataLoader().extract_native_types("/nonexistent", {}) is None From 857f5cf2d37fdfdfa57bef9dd9a79089616b9fc6 Mon Sep 17 00:00:00 2001 From: Irozuku Date: Thu, 28 May 2026 16:59:48 -0400 Subject: [PATCH 6/6] test: include supports_native_types in dataloader metadata fixtures BaseDataLoader.get_metadata now exposes the supports_native_types flag for the frontend toggle. Update test_components_api fixtures to match the new metadata dict shape (defaults to False for stock test loaders). --- tests/back/api/test_components_api.py | 114 +++++++++++++++++++++----- 1 file changed, 95 insertions(+), 19 deletions(-) diff --git a/tests/back/api/test_components_api.py b/tests/back/api/test_components_api.py index 1fe5994e6..26cd14699 100644 --- a/tests/back/api/test_components_api.py +++ b/tests/back/api/test_components_api.py @@ -191,7 +191,11 @@ def test_get_component_by_id(client: TestClient): "type": "DataLoader", "configurable_object": True, "schema": {}, - "metadata": {"category": "File Uploading", "supported_extensions": []}, + "metadata": { + "category": "File Uploading", + "supported_extensions": [], + "supports_native_types": False, + }, "description": None, "display_name": None, "color": None, @@ -318,7 +322,11 @@ def test_get_components_select_only_dataloaders(client: TestClient): "type": "DataLoader", "configurable_object": True, "schema": {}, - "metadata": {"category": "File Uploading", "supported_extensions": []}, + "metadata": { + "category": "File Uploading", + "supported_extensions": [], + "supports_native_types": False, + }, "description": None, "display_name": None, "color": None, @@ -328,7 +336,11 @@ def test_get_components_select_only_dataloaders(client: TestClient): "type": "DataLoader", "configurable_object": True, "schema": {}, - "metadata": {"category": "File Uploading", "supported_extensions": []}, + "metadata": { + "category": "File Uploading", + "supported_extensions": [], + "supports_native_types": False, + }, "description": None, "display_name": None, "color": None, @@ -338,7 +350,11 @@ def test_get_components_select_only_dataloaders(client: TestClient): "type": "DataLoader", "configurable_object": True, "schema": {}, - "metadata": {"category": "File Uploading", "supported_extensions": []}, + "metadata": { + "category": "File Uploading", + "supported_extensions": [], + "supports_native_types": False, + }, "description": None, "display_name": None, "color": None, @@ -443,7 +459,11 @@ def test_get_components_ignore_models(client: TestClient): "type": "DataLoader", "configurable_object": True, "schema": {}, - "metadata": {"category": "File Uploading", "supported_extensions": []}, + "metadata": { + "category": "File Uploading", + "supported_extensions": [], + "supports_native_types": False, + }, "description": None, "display_name": None, "color": None, @@ -453,7 +473,11 @@ def test_get_components_ignore_models(client: TestClient): "type": "DataLoader", "configurable_object": True, "schema": {}, - "metadata": {"category": "File Uploading", "supported_extensions": []}, + "metadata": { + "category": "File Uploading", + "supported_extensions": [], + "supports_native_types": False, + }, "description": None, "display_name": None, "color": None, @@ -463,7 +487,11 @@ def test_get_components_ignore_models(client: TestClient): "type": "DataLoader", "configurable_object": True, "schema": {}, - "metadata": {"category": "File Uploading", "supported_extensions": []}, + "metadata": { + "category": "File Uploading", + "supported_extensions": [], + "supports_native_types": False, + }, "description": None, "display_name": None, "color": None, @@ -481,7 +509,11 @@ def test_get_components_ignore_tasks_and_models(client: TestClient): "type": "DataLoader", "configurable_object": True, "schema": {}, - "metadata": {"category": "File Uploading", "supported_extensions": []}, + "metadata": { + "category": "File Uploading", + "supported_extensions": [], + "supports_native_types": False, + }, "description": None, "display_name": None, "color": None, @@ -491,7 +523,11 @@ def test_get_components_ignore_tasks_and_models(client: TestClient): "type": "DataLoader", "configurable_object": True, "schema": {}, - "metadata": {"category": "File Uploading", "supported_extensions": []}, + "metadata": { + "category": "File Uploading", + "supported_extensions": [], + "supports_native_types": False, + }, "description": None, "display_name": None, "color": None, @@ -501,7 +537,11 @@ def test_get_components_ignore_tasks_and_models(client: TestClient): "type": "DataLoader", "configurable_object": True, "schema": {}, - "metadata": {"category": "File Uploading", "supported_extensions": []}, + "metadata": { + "category": "File Uploading", + "supported_extensions": [], + "supports_native_types": False, + }, "description": None, "display_name": None, "color": None, @@ -605,7 +645,11 @@ def test_get_components_dataloader_component_parent(client: TestClient): "type": "DataLoader", "configurable_object": True, "schema": {}, - "metadata": {"category": "File Uploading", "supported_extensions": []}, + "metadata": { + "category": "File Uploading", + "supported_extensions": [], + "supports_native_types": False, + }, "description": None, "display_name": None, "color": None, @@ -615,7 +659,11 @@ def test_get_components_dataloader_component_parent(client: TestClient): "type": "DataLoader", "configurable_object": True, "schema": {}, - "metadata": {"category": "File Uploading", "supported_extensions": []}, + "metadata": { + "category": "File Uploading", + "supported_extensions": [], + "supports_native_types": False, + }, "description": None, "display_name": None, "color": None, @@ -650,7 +698,11 @@ def test_get_components_by_type_and_task(client: TestClient): "type": "DataLoader", "configurable_object": True, "schema": {}, - "metadata": {"category": "File Uploading", "supported_extensions": []}, + "metadata": { + "category": "File Uploading", + "supported_extensions": [], + "supports_native_types": False, + }, "description": None, "display_name": None, "color": None, @@ -660,7 +712,11 @@ def test_get_components_by_type_and_task(client: TestClient): "type": "DataLoader", "configurable_object": True, "schema": {}, - "metadata": {"category": "File Uploading", "supported_extensions": []}, + "metadata": { + "category": "File Uploading", + "supported_extensions": [], + "supports_native_types": False, + }, "description": None, "display_name": None, "color": None, @@ -694,7 +750,11 @@ def test_get_components_select_and_ignore_by_type(client: TestClient): "type": "DataLoader", "configurable_object": True, "schema": {}, - "metadata": {"category": "File Uploading", "supported_extensions": []}, + "metadata": { + "category": "File Uploading", + "supported_extensions": [], + "supports_native_types": False, + }, "description": None, "display_name": None, "color": None, @@ -704,7 +764,11 @@ def test_get_components_select_and_ignore_by_type(client: TestClient): "type": "DataLoader", "configurable_object": True, "schema": {}, - "metadata": {"category": "File Uploading", "supported_extensions": []}, + "metadata": { + "category": "File Uploading", + "supported_extensions": [], + "supports_native_types": False, + }, "description": None, "display_name": None, "color": None, @@ -714,7 +778,11 @@ def test_get_components_select_and_ignore_by_type(client: TestClient): "type": "DataLoader", "configurable_object": True, "schema": {}, - "metadata": {"category": "File Uploading", "supported_extensions": []}, + "metadata": { + "category": "File Uploading", + "supported_extensions": [], + "supports_native_types": False, + }, "description": None, "display_name": None, "color": None, @@ -735,7 +803,11 @@ def test_get_components_select_type_and_parent(client: TestClient): "type": "DataLoader", "configurable_object": True, "schema": {}, - "metadata": {"category": "File Uploading", "supported_extensions": []}, + "metadata": { + "category": "File Uploading", + "supported_extensions": [], + "supports_native_types": False, + }, "description": None, "display_name": None, "color": None, @@ -745,7 +817,11 @@ def test_get_components_select_type_and_parent(client: TestClient): "type": "DataLoader", "configurable_object": True, "schema": {}, - "metadata": {"category": "File Uploading", "supported_extensions": []}, + "metadata": { + "category": "File Uploading", + "supported_extensions": [], + "supports_native_types": False, + }, "description": None, "display_name": None, "color": None,