77from datasets import load_dataset
88
99from DashAI .back .core .schema_fields import (
10+ bool_field ,
1011 enum_field ,
12+ int_field ,
1113 none_type ,
1214 schema_field ,
1315 string_field ,
@@ -30,18 +32,102 @@ class CSVDataloaderSchema(BaseSchema):
3032 ),
3133 ) # type: ignore
3234 separator : schema_field (
33- enum_field (["," , ";" , "\u0020 " , "\t " ]),
35+ enum_field (["," , ";" , "blank space " , "tab " ]),
3436 "," ,
3537 "A separator character delimits the data in a CSV file." ,
3638 ) # type: ignore
3739
40+ header : schema_field (
41+ string_field (),
42+ "infer" ,
43+ (
44+ "Row number(s) containing column labels and marking the start of the data "
45+ "(zero-indexed). Default behavior is to infer the column names. If column "
46+ "names are passed explicitly, this should be set to '0'. "
47+ "Header can also be a list of integers that specify row locations "
48+ "for MultiIndex on the columns."
49+ ),
50+ ) # type: ignore
51+
52+ names : schema_field (
53+ none_type (string_field ()),
54+ None ,
55+ (
56+ "Comma-separated list of column names to use. If the file contains a "
57+ "header row, "
58+ "then you should explicitly pass header=0 to override the column names. "
59+ "Example: 'col1,col2,col3'. Leave empty to use file headers."
60+ ),
61+ ) # type: ignore
62+
63+ encoding : schema_field (
64+ enum_field (["utf-8" , "latin1" , "cp1252" , "iso-8859-1" ]),
65+ "utf-8" ,
66+ "Encoding to use for UTF when reading/writing. Most common encodings provided." ,
67+ ) # type: ignore
68+
69+ na_values : schema_field (
70+ none_type (string_field ()),
71+ None ,
72+ (
73+ "Comma-separated additional strings to recognize as NA/NaN. "
74+ "Example: 'NULL,missing,n/a'"
75+ ),
76+ ) # type: ignore
77+
78+ keep_default_na : schema_field (
79+ bool_field (),
80+ True ,
81+ (
82+ "Whether to include the default NaN values when parsing the data "
83+ "(True recommended)."
84+ ),
85+ ) # type: ignore
86+
87+ true_values : schema_field (
88+ none_type (string_field ()),
89+ None ,
90+ "Comma-separated values to consider as True. Example: 'yes,true,1,on'" ,
91+ ) # type: ignore
92+
93+ false_values : schema_field (
94+ none_type (string_field ()),
95+ None ,
96+ "Comma-separated values to consider as False. Example: 'no,false,0,off'" ,
97+ ) # type: ignore
98+
99+ skip_blank_lines : schema_field (
100+ bool_field (),
101+ True ,
102+ "If True, skip over blank lines rather than interpreting as NaN values." ,
103+ ) # type: ignore
104+
105+ skiprows : schema_field (
106+ none_type (int_field ()),
107+ None ,
108+ "Number of lines to skip at the beginning of the file. "
109+ "Leave empty to skip none." ,
110+ ) # type: ignore
111+
112+ nrows : schema_field (
113+ none_type (int_field ()),
114+ None ,
115+ "Number of rows to read from the file. Leave empty to read all rows." ,
116+ ) # type: ignore
117+
38118
39119class CSVDataLoader (BaseDataLoader ):
40120 """Data loader for tabular data in CSV files."""
41121
42122 COMPATIBLE_COMPONENTS = ["TabularClassificationTask" ]
43123 SCHEMA = CSVDataloaderSchema
44124
125+ DESCRIPTION : str = """
126+ Data loader for tabular data in CSV files.
127+ All uploaded CSV files must have the same column structure and use
128+ consistent separators.
129+ """
130+
45131 def _check_params (
46132 self ,
47133 params : Dict [str , Any ],
@@ -51,12 +137,49 @@ def _check_params(
51137 "Error trying to load the CSV dataset: "
52138 "separator parameter was not provided."
53139 )
54- separator = params ["separator" ]
55140
141+ clean_params = {}
142+
143+ separator = params ["separator" ]
144+ if separator == "blank space" :
145+ separator = " "
146+ elif separator == "tab" :
147+ separator = "\t "
56148 if not isinstance (separator , str ):
57149 raise TypeError (
58150 f"Param separator should be a string, got { type (params ['separator' ])} "
59151 )
152+ clean_params ["delimiter" ] = separator
153+
154+ if params .get ("header" ) is not None :
155+ clean_params ["header" ] = params ["header" ]
156+
157+ list_params = ["names" , "na_values" , "true_values" , "false_values" ]
158+ for param in list_params :
159+ if param in params and params [param ]:
160+ clean_params [param ] = [val .strip () for val in params [param ].split ("," )]
161+
162+ bool_params = ["keep_default_na" , "skip_blank_lines" ]
163+ for param in bool_params :
164+ if param in params and params [param ] is not None :
165+ clean_params [param ] = params [param ]
166+
167+ int_params = ["skiprows" , "nrows" ]
168+ for param in int_params :
169+ if param in params and params [param ] is not None :
170+ if not isinstance (params [param ], int ):
171+ raise TypeError (
172+ f"Param { param } should be an integer, got { type (params [param ])} "
173+ )
174+ clean_params [param ] = params [param ]
175+
176+ if "encoding" in params and params ["encoding" ]:
177+ valid_encodings = ["utf-8" , "latin1" , "cp1252" , "iso-8859-1" ]
178+ if params ["encoding" ] not in valid_encodings :
179+ raise ValueError (f"Invalid encoding: { params ['encoding' ]} " )
180+ clean_params ["encoding" ] = params ["encoding" ]
181+
182+ return clean_params
60183
61184 @beartype
62185 def load_data (
@@ -83,20 +206,21 @@ def load_data(
83206 DatasetDict
84207 A HuggingFace's Dataset with the loaded data.
85208 """
86- self ._check_params (params )
87- separator = params ["separator" ]
209+ print ("parameters are" , params )
210+ clean_params = self ._check_params (params )
211+ print ("cleaned parameters are" , clean_params )
88212 prepared_path = self .prepare_files (filepath_or_buffer , temp_path )
89213 if prepared_path [1 ] == "file" :
90214 dataset = load_dataset (
91215 "csv" ,
92216 data_files = prepared_path [0 ],
93- delimiter = separator ,
217+ ** clean_params ,
94218 )
95219 else :
96220 dataset = load_dataset (
97221 "csv" ,
98222 data_dir = prepared_path [0 ],
99- delimiter = separator ,
223+ ** clean_params ,
100224 )
101225 shutil .rmtree (prepared_path [0 ])
102226
0 commit comments