kaggle-prep 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- kaggle_prep-0.1.0/LICENSE +21 -0
- kaggle_prep-0.1.0/PKG-INFO +51 -0
- kaggle_prep-0.1.0/README.md +27 -0
- kaggle_prep-0.1.0/kaggle_prep/__init__.py +18 -0
- kaggle_prep-0.1.0/kaggle_prep/cli.py +451 -0
- kaggle_prep-0.1.0/kaggle_prep/notebook.py +584 -0
- kaggle_prep-0.1.0/kaggle_prep/profiler.py +268 -0
- kaggle_prep-0.1.0/kaggle_prep/report.py +309 -0
- kaggle_prep-0.1.0/kaggle_prep/visualizer.py +469 -0
- kaggle_prep-0.1.0/kaggle_prep.egg-info/PKG-INFO +51 -0
- kaggle_prep-0.1.0/kaggle_prep.egg-info/SOURCES.txt +15 -0
- kaggle_prep-0.1.0/kaggle_prep.egg-info/dependency_links.txt +1 -0
- kaggle_prep-0.1.0/kaggle_prep.egg-info/entry_points.txt +2 -0
- kaggle_prep-0.1.0/kaggle_prep.egg-info/requires.txt +5 -0
- kaggle_prep-0.1.0/kaggle_prep.egg-info/top_level.txt +1 -0
- kaggle_prep-0.1.0/pyproject.toml +38 -0
- kaggle_prep-0.1.0/setup.cfg +4 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Your Name
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: kaggle-prep
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: One-command Kaggle dataset preparation & analysis tool
|
|
5
|
+
Author-email: Sumit Gavali <sumitrg0007@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Keywords: kaggle,data-science,cli,automation
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE
|
|
18
|
+
Requires-Dist: pandas>=1.3.0
|
|
19
|
+
Requires-Dist: kaggle>=1.5.0
|
|
20
|
+
Requires-Dist: matplotlib>=3.4.0
|
|
21
|
+
Requires-Dist: seaborn>=0.11.0
|
|
22
|
+
Requires-Dist: numpy>=1.21.0
|
|
23
|
+
Dynamic: license-file
|
|
24
|
+
|
|
25
|
+
# Kaggle Prep
|
|
26
|
+
|
|
27
|
+
> **One command to download, profile, visualize, and prepare any Kaggle dataset!**
|
|
28
|
+
|
|
29
|
+
## Features
|
|
30
|
+
|
|
31
|
+
- Download any Kaggle dataset
|
|
32
|
+
- Profile your data instantly
|
|
33
|
+
- Generate beautiful HTML reports
|
|
34
|
+
- Create 10+ EDA visualizations
|
|
35
|
+
- Auto-generate preprocessing code
|
|
36
|
+
- Create starter Jupyter notebooks
|
|
37
|
+
|
|
38
|
+
## Quick Start
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# Install
|
|
42
|
+
pip install kaggle-prep
|
|
43
|
+
|
|
44
|
+
# Setup credentials
|
|
45
|
+
kaggle-prep --setup
|
|
46
|
+
|
|
47
|
+
# Download a dataset
|
|
48
|
+
kaggle-prep uciml/iris
|
|
49
|
+
|
|
50
|
+
# Full analysis
|
|
51
|
+
kaggle-prep uciml/iris --profile --report --visualize --preprocess --notebook
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Kaggle Prep
|
|
2
|
+
|
|
3
|
+
> **One command to download, profile, visualize, and prepare any Kaggle dataset!**
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Download any Kaggle dataset
|
|
8
|
+
- Profile your data instantly
|
|
9
|
+
- Generate beautiful HTML reports
|
|
10
|
+
- Create 10+ EDA visualizations
|
|
11
|
+
- Auto-generate preprocessing code
|
|
12
|
+
- Create starter Jupyter notebooks
|
|
13
|
+
|
|
14
|
+
## Quick Start
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# Install
|
|
18
|
+
pip install kaggle-prep
|
|
19
|
+
|
|
20
|
+
# Setup credentials
|
|
21
|
+
kaggle-prep --setup
|
|
22
|
+
|
|
23
|
+
# Download a dataset
|
|
24
|
+
kaggle-prep uciml/iris
|
|
25
|
+
|
|
26
|
+
# Full analysis
|
|
27
|
+
kaggle-prep uciml/iris --profile --report --visualize --preprocess --notebook
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
__version__="0.1.0"
|
|
2
|
+
__author__="Sumit Gavali"
|
|
3
|
+
__email__="Sumitrg0007@gmail.com"
|
|
4
|
+
|
|
5
|
+
from .cli import main
|
|
6
|
+
from .profiler import DataProfiler
|
|
7
|
+
from .report import generate_standalone_report
|
|
8
|
+
from .visualizer import generate_eda_plots
|
|
9
|
+
from .notebook import generate_notebook
|
|
10
|
+
|
|
11
|
+
__version__ = "0.1.0"
|
|
12
|
+
__all__ = [
|
|
13
|
+
'main',
|
|
14
|
+
'DataProfiler',
|
|
15
|
+
'generate_standalone_report',
|
|
16
|
+
'generate_eda_plots',
|
|
17
|
+
'generate_notebook'
|
|
18
|
+
]
|
|
@@ -0,0 +1,451 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
import os
|
|
4
|
+
import profile
|
|
5
|
+
import time
|
|
6
|
+
import pandas as pd
|
|
7
|
+
from kaggle.api.kaggle_api_extended import KaggleApi
|
|
8
|
+
from .notebook import generate_notebook
|
|
9
|
+
from .visualizer import generate_eda_plots, generate_preprocessing_code
|
|
10
|
+
|
|
11
|
+
# Import our custom profiler and report generator
|
|
12
|
+
from .profiler import DataProfiler, save_profile_json, print_profile_summary
|
|
13
|
+
from .report import generate_standalone_report
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# ============================================================
|
|
17
|
+
# FUNCTION 1: Parse Arguments
|
|
18
|
+
# ============================================================
|
|
19
|
+
def parse_arguments():
|
|
20
|
+
"""Parse and return command line arguments"""
|
|
21
|
+
parser = argparse.ArgumentParser(
|
|
22
|
+
description="Prepare Kaggle datasets for data analysis."
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
parser.add_argument(
|
|
26
|
+
"dataset",
|
|
27
|
+
help="Kaggle dataset identifier, e.g. adyen/dabstep-benchmark"
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
parser.add_argument(
|
|
31
|
+
"--output-dir",
|
|
32
|
+
default="data",
|
|
33
|
+
help="Directory to save downloaded data (default: data)"
|
|
34
|
+
)
|
|
35
|
+
parser.add_argument(
|
|
36
|
+
"--notebook",
|
|
37
|
+
action="store_true",
|
|
38
|
+
help="Generate a Jupyter notebook with EDA and preprocessing code"
|
|
39
|
+
)
|
|
40
|
+
parser.add_argument(
|
|
41
|
+
"--verbose",
|
|
42
|
+
action="store_true",
|
|
43
|
+
help="Enable verbose output for debugging"
|
|
44
|
+
)
|
|
45
|
+
parser.add_argument(
|
|
46
|
+
"--local",
|
|
47
|
+
action="store_true",
|
|
48
|
+
help="Use existing data - works with --profile, --report, etc"
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
parser.add_argument(
|
|
53
|
+
"--competition",
|
|
54
|
+
action="store_true",
|
|
55
|
+
help="Download from competition instead of dataset"
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
parser.add_argument(
|
|
59
|
+
"--profile",
|
|
60
|
+
action="store_true",
|
|
61
|
+
help="Generate data profile after download"
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
parser.add_argument(
|
|
65
|
+
"--report",
|
|
66
|
+
action="store_true",
|
|
67
|
+
help="Generate a standalone HTML report after download"
|
|
68
|
+
)
|
|
69
|
+
parser.add_argument(
|
|
70
|
+
"--visualize",
|
|
71
|
+
action="store_true",
|
|
72
|
+
help="generate EDA visualization (plots)"
|
|
73
|
+
)
|
|
74
|
+
parser.add_argument(
|
|
75
|
+
"--preprocess",
|
|
76
|
+
action="store_true",
|
|
77
|
+
help="generate preprocessing code"
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
return parser.parse_args()
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
# ============================================================
|
|
84
|
+
# FUNCTION 2: Display Initial Info
|
|
85
|
+
# ============================================================
|
|
86
|
+
def display_startup_info(args):
|
|
87
|
+
"""Display startup information"""
|
|
88
|
+
if args.verbose:
|
|
89
|
+
print(f"š¦ Dataset: {args.dataset}")
|
|
90
|
+
print(f"š Output directory: {args.output_dir}")
|
|
91
|
+
if args.competition:
|
|
92
|
+
print(f"š Competition mode enabled")
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
# ============================================================
|
|
96
|
+
# FUNCTION 3: Check Credentials
|
|
97
|
+
# ============================================================
|
|
98
|
+
def check_credentials(verbose=False):
|
|
99
|
+
"""Check if Kaggle credentials exist"""
|
|
100
|
+
kaggle_dir = Path.home() / ".kaggle"
|
|
101
|
+
kaggle_json = kaggle_dir / "kaggle.json"
|
|
102
|
+
|
|
103
|
+
if not kaggle_json.exists():
|
|
104
|
+
print(f"ā Kaggle credentials not found at: {kaggle_json}")
|
|
105
|
+
print("\nš To get credentials:")
|
|
106
|
+
print(" 1. Go to https://www.kaggle.com/settings/api")
|
|
107
|
+
print(" 2. Click 'Create New Token'")
|
|
108
|
+
print(f" 3. Save kaggle.json to: {kaggle_dir}")
|
|
109
|
+
return None
|
|
110
|
+
|
|
111
|
+
if verbose:
|
|
112
|
+
print(f"ā
Found Kaggle credentials at: {kaggle_json}")
|
|
113
|
+
|
|
114
|
+
return kaggle_dir
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
# ============================================================
|
|
118
|
+
# FUNCTION 4: Authenticate
|
|
119
|
+
# ============================================================
|
|
120
|
+
def authenticate_kaggle(kaggle_dir, verbose=False):
|
|
121
|
+
"""Authenticate with Kaggle API"""
|
|
122
|
+
print(f"š Authenticating with Kaggle API...")
|
|
123
|
+
|
|
124
|
+
try:
|
|
125
|
+
os.environ['KAGGLE_CONFIG_DIR'] = str(kaggle_dir)
|
|
126
|
+
api = KaggleApi()
|
|
127
|
+
api.authenticate()
|
|
128
|
+
|
|
129
|
+
if verbose:
|
|
130
|
+
print(f"ā
Authentication successful!")
|
|
131
|
+
|
|
132
|
+
return api
|
|
133
|
+
|
|
134
|
+
except Exception as e:
|
|
135
|
+
print(f"ā Authentication error: {e}")
|
|
136
|
+
print("\nš Troubleshooting:")
|
|
137
|
+
print(" 1. Make sure kaggle.json is not empty")
|
|
138
|
+
print(" 2. Try re-downloading from Kaggle settings")
|
|
139
|
+
print(" 3. Check your internet connection")
|
|
140
|
+
return None
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
# ============================================================
|
|
144
|
+
# FUNCTION 5: Create Output Directory
|
|
145
|
+
# ============================================================
|
|
146
|
+
def create_output_directory(output_dir):
|
|
147
|
+
"""Create output directory if it doesn't exist"""
|
|
148
|
+
output_path = Path(output_dir)
|
|
149
|
+
output_path.mkdir(parents=True, exist_ok=True)
|
|
150
|
+
return output_path
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
# ============================================================
|
|
154
|
+
# FUNCTION 6: Format File Size
|
|
155
|
+
# ============================================================
|
|
156
|
+
def format_file_size(size_bytes):
|
|
157
|
+
"""Convert bytes to human-readable format"""
|
|
158
|
+
if size_bytes > 1024 * 1024 * 1024: # GB
|
|
159
|
+
return f"{size_bytes/(1024*1024*1024):.2f} GB"
|
|
160
|
+
elif size_bytes > 1024 * 1024: # MB
|
|
161
|
+
return f"{size_bytes/(1024*1024):.1f} MB"
|
|
162
|
+
elif size_bytes > 1024: # KB
|
|
163
|
+
return f"{size_bytes/1024:.1f} KB"
|
|
164
|
+
else:
|
|
165
|
+
return f"{size_bytes} bytes"
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
# ============================================================
|
|
169
|
+
# FUNCTION 7: List Files
|
|
170
|
+
# ============================================================
|
|
171
|
+
def list_downloaded_files(output_path):
|
|
172
|
+
"""List all downloaded files with sizes"""
|
|
173
|
+
print("\nš Downloaded files:")
|
|
174
|
+
|
|
175
|
+
files = list(output_path.rglob("*"))
|
|
176
|
+
if not files:
|
|
177
|
+
print(" No files found!")
|
|
178
|
+
return
|
|
179
|
+
|
|
180
|
+
for file in files:
|
|
181
|
+
if file.is_file():
|
|
182
|
+
size = file.stat().st_size
|
|
183
|
+
size_str = format_file_size(size)
|
|
184
|
+
print(f" - {file.name} ({size_str})")
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
# ============================================================
|
|
188
|
+
# FUNCTION 8: Load First CSV
|
|
189
|
+
# ============================================================
|
|
190
|
+
def load_first_csv(data_path):
|
|
191
|
+
"""Load the first CSV file found in the directory"""
|
|
192
|
+
csv_files = list(Path(data_path).rglob("*.csv"))
|
|
193
|
+
|
|
194
|
+
if not csv_files:
|
|
195
|
+
print("ā No CSV files found to profile!")
|
|
196
|
+
return None
|
|
197
|
+
|
|
198
|
+
try:
|
|
199
|
+
df = pd.read_csv(csv_files[0])
|
|
200
|
+
print(f"š Loaded: {csv_files[0].name} ({len(df):,} rows, {len(df.columns)} columns)")
|
|
201
|
+
return df
|
|
202
|
+
except Exception as e:
|
|
203
|
+
print(f"ā Error loading CSV: {e}")
|
|
204
|
+
return None
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
# ============================================================
|
|
208
|
+
# FUNCTION 9: Download Dataset
|
|
209
|
+
# ============================================================
|
|
210
|
+
def download_dataset(api, dataset_name, output_path, verbose=False):
|
|
211
|
+
"""Download a dataset from Kaggle"""
|
|
212
|
+
print(f"ā¬ļø Downloading {dataset_name}...")
|
|
213
|
+
|
|
214
|
+
try:
|
|
215
|
+
api.dataset_download_files(
|
|
216
|
+
dataset_name,
|
|
217
|
+
path=str(output_path),
|
|
218
|
+
unzip=True
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
print(f"ā
Download complete! Files saved to: {output_path}")
|
|
222
|
+
|
|
223
|
+
if verbose:
|
|
224
|
+
list_downloaded_files(output_path)
|
|
225
|
+
|
|
226
|
+
return True
|
|
227
|
+
|
|
228
|
+
except Exception as e:
|
|
229
|
+
handle_download_error(e, dataset_name)
|
|
230
|
+
return False
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
# ============================================================
|
|
234
|
+
# FUNCTION 10: Download Competition
|
|
235
|
+
# ============================================================
|
|
236
|
+
def download_competition(api, competition_name, output_path, verbose=False):
|
|
237
|
+
"""Download competition files from Kaggle"""
|
|
238
|
+
print(f"ā¬ļø Downloading competition: {competition_name}...")
|
|
239
|
+
|
|
240
|
+
try:
|
|
241
|
+
api.competition_download_files(
|
|
242
|
+
competition_name,
|
|
243
|
+
path=str(output_path)
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
print(f"ā
Download complete! Files saved to: {output_path}")
|
|
247
|
+
|
|
248
|
+
if verbose:
|
|
249
|
+
list_downloaded_files(output_path)
|
|
250
|
+
|
|
251
|
+
return True
|
|
252
|
+
|
|
253
|
+
except Exception as e:
|
|
254
|
+
handle_download_error(e, competition_name)
|
|
255
|
+
return False
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
# ============================================================
|
|
259
|
+
# FUNCTION 11: Handle Download Errors
|
|
260
|
+
# ============================================================
|
|
261
|
+
def handle_download_error(error, dataset_name):
|
|
262
|
+
"""Handle and explain download errors"""
|
|
263
|
+
print(f"ā Error downloading: {error}")
|
|
264
|
+
error_msg = str(error)
|
|
265
|
+
|
|
266
|
+
if "403" in error_msg:
|
|
267
|
+
print("\nš Troubleshooting 403 Forbidden error:")
|
|
268
|
+
print("This usually means the dataset requires accepting terms or is restricted.")
|
|
269
|
+
print(f"1. Visit: https://www.kaggle.com/datasets/{dataset_name}")
|
|
270
|
+
print("2. Click 'Download' and accept any terms")
|
|
271
|
+
print("3. Wait a moment, then try again")
|
|
272
|
+
print("\nš Or try --competition flag if it's a competition:")
|
|
273
|
+
print(f" python kaggle_prep/cli.py {dataset_name} --competition --verbose")
|
|
274
|
+
|
|
275
|
+
elif "404" in error_msg:
|
|
276
|
+
print(f"\nš Dataset '{dataset_name}' not found!")
|
|
277
|
+
print("Check the spelling or try searching on Kaggle")
|
|
278
|
+
print("\nš Examples:")
|
|
279
|
+
print(" python kaggle_prep/cli.py uciml/iris --verbose")
|
|
280
|
+
print(" python kaggle_prep/cli.py debayank2024/netflix-movies-and-series --verbose")
|
|
281
|
+
|
|
282
|
+
elif "429" in error_msg:
|
|
283
|
+
print("\nā ļø Rate limit reached!")
|
|
284
|
+
print("Kaggle limits how many requests you can make.")
|
|
285
|
+
print("Wait 1 hour and try again.")
|
|
286
|
+
|
|
287
|
+
else:
|
|
288
|
+
print(f"\nš Unexpected error: {error}")
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
# ============================================================
|
|
292
|
+
# FUNCTION 12: Profile Downloaded Data
|
|
293
|
+
# ============================================================
|
|
294
|
+
def profile_downloaded_data(output_path, dataset_name, generate_report=False):
|
|
295
|
+
"""Run profiling on downloaded data"""
|
|
296
|
+
|
|
297
|
+
print("\nš Generating data profile...")
|
|
298
|
+
|
|
299
|
+
# Load the data
|
|
300
|
+
df = load_first_csv(Path(output_path))
|
|
301
|
+
if df is None:
|
|
302
|
+
return
|
|
303
|
+
|
|
304
|
+
# Create profile using our custom profiler
|
|
305
|
+
profiler = DataProfiler(df, dataset_name)
|
|
306
|
+
profile = profiler.profile()
|
|
307
|
+
|
|
308
|
+
# Save JSON profile
|
|
309
|
+
json_path = save_profile_json(profile)
|
|
310
|
+
|
|
311
|
+
# Print summary to console
|
|
312
|
+
print_profile_summary(profile)
|
|
313
|
+
|
|
314
|
+
# Generate HTML report if requested
|
|
315
|
+
if generate_report:
|
|
316
|
+
generate_standalone_report(profile)
|
|
317
|
+
|
|
318
|
+
def generate_starter_notebook(output_path, dataset_name, df=None, profile=None):
|
|
319
|
+
print("Generating starter notebook...")
|
|
320
|
+
if df is None:
|
|
321
|
+
df=load_first_csv(output_path)
|
|
322
|
+
|
|
323
|
+
notebook_path = generate_notebook(
|
|
324
|
+
dataset_name=dataset_name,
|
|
325
|
+
df=df,
|
|
326
|
+
profile=profile,
|
|
327
|
+
output_dir="notebooks"
|
|
328
|
+
)
|
|
329
|
+
print(f" Starter notebook saved to: {notebook_path}")
|
|
330
|
+
|
|
331
|
+
#===============================================================
|
|
332
|
+
def generate_visualizations(output_path, dataset_name,df):
|
|
333
|
+
print("Generating EDA visualizations..")
|
|
334
|
+
|
|
335
|
+
vis_dir =f"eda_plots_{dataset_name.replace('/','_')}"
|
|
336
|
+
|
|
337
|
+
plot_path = generate_eda_plots(
|
|
338
|
+
df=df,
|
|
339
|
+
output_dir=vis_dir,
|
|
340
|
+
max_cols=10,
|
|
341
|
+
fig_dpi=150
|
|
342
|
+
)
|
|
343
|
+
|
|
344
|
+
print(f" Visualizations saved to: {plot_path}")
|
|
345
|
+
return plot_path
|
|
346
|
+
##==============================================
|
|
347
|
+
def save_preprocessing_code(output_path, dataset_name, df):
|
|
348
|
+
"""Generate and save preprocessing code"""
|
|
349
|
+
|
|
350
|
+
print("\n Generating preprocessing code...")
|
|
351
|
+
|
|
352
|
+
# Generate code
|
|
353
|
+
code = generate_preprocessing_code(df)
|
|
354
|
+
|
|
355
|
+
# Save to file
|
|
356
|
+
safe_name = dataset_name.replace('/', '_')
|
|
357
|
+
code_path = Path(output_path) / f"{safe_name}_preprocess.py"
|
|
358
|
+
|
|
359
|
+
with open(code_path, 'w', encoding='utf-8') as f:
|
|
360
|
+
f.write(code)
|
|
361
|
+
|
|
362
|
+
print(f" Preprocessing code saved to: {code_path}")
|
|
363
|
+
return code_path
|
|
364
|
+
|
|
365
|
+
# ============================================================
|
|
366
|
+
# MAIN FUNCTION
|
|
367
|
+
# ============================================================
|
|
368
|
+
def main():
|
|
369
|
+
"""Main entry point for the CLI tool"""
|
|
370
|
+
|
|
371
|
+
# Step 1: Get user input
|
|
372
|
+
args = parse_arguments()
|
|
373
|
+
|
|
374
|
+
# Step 2: Show startup info
|
|
375
|
+
display_startup_info(args)
|
|
376
|
+
output_path = Path(args.output_dir)
|
|
377
|
+
data_exists = any(output_path.glob("*.csv")) or any(output_path.glob("*.xlsx")) or any(output_path.glob("*.json"))
|
|
378
|
+
|
|
379
|
+
if args.local and data_exists:
|
|
380
|
+
print("š Using existing data (--local flag detected)")
|
|
381
|
+
print(f" Data found in: {output_path}")
|
|
382
|
+
else:
|
|
383
|
+
# Only download if:
|
|
384
|
+
# 1. --local is NOT used, OR
|
|
385
|
+
# 2. Data doesn't exist
|
|
386
|
+
if not data_exists:
|
|
387
|
+
print("š No existing data found. Downloading...")
|
|
388
|
+
else:
|
|
389
|
+
print("š„ Downloading data (use --local to skip download next time)")
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
# Step 3: Check credentials
|
|
393
|
+
kaggle_dir = check_credentials(args.verbose)
|
|
394
|
+
if not kaggle_dir:
|
|
395
|
+
return
|
|
396
|
+
|
|
397
|
+
# Step 4: Authenticate
|
|
398
|
+
api = authenticate_kaggle(kaggle_dir, args.verbose)
|
|
399
|
+
if not api:
|
|
400
|
+
return
|
|
401
|
+
|
|
402
|
+
# Step 5: Create output directory
|
|
403
|
+
output_path = create_output_directory(args.output_dir)
|
|
404
|
+
|
|
405
|
+
# Step 6: Download
|
|
406
|
+
if args.competition:
|
|
407
|
+
download_competition(api, args.dataset, output_path, args.verbose)
|
|
408
|
+
else:
|
|
409
|
+
download_dataset(api, args.dataset, output_path, args.verbose)
|
|
410
|
+
|
|
411
|
+
df=None
|
|
412
|
+
profile=None
|
|
413
|
+
if args.profile or args.report or args.visualize or args.preprocess or args.notebook:
|
|
414
|
+
df = load_first_csv(Path(args.output_dir))
|
|
415
|
+
|
|
416
|
+
# If data loaded successfully
|
|
417
|
+
if df is not None:
|
|
418
|
+
# Generate profile if requested
|
|
419
|
+
if args.profile or args.report:
|
|
420
|
+
profiler = DataProfiler(df, args.dataset)
|
|
421
|
+
profile = profiler.profile()
|
|
422
|
+
|
|
423
|
+
if args.profile:
|
|
424
|
+
json_path = save_profile_json(profile)
|
|
425
|
+
|
|
426
|
+
if args.report:
|
|
427
|
+
generate_standalone_report(profile)
|
|
428
|
+
|
|
429
|
+
# Step 7: Profile if requested
|
|
430
|
+
if args.visualize:
|
|
431
|
+
generate_visualizations(output_path, args.dataset, df)
|
|
432
|
+
|
|
433
|
+
# Generate preprocessing code if requested
|
|
434
|
+
if args.preprocess:
|
|
435
|
+
save_preprocessing_code(output_path, args.dataset, df)
|
|
436
|
+
|
|
437
|
+
# Generate notebook if requested
|
|
438
|
+
if args.notebook:
|
|
439
|
+
generate_starter_notebook(args.dataset, df, profile)
|
|
440
|
+
|
|
441
|
+
# Step 8: Done!
|
|
442
|
+
print("\n All done! Happy data science! ")
|
|
443
|
+
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
# ============================================================
|
|
448
|
+
# ENTRY POINT
|
|
449
|
+
# ============================================================
|
|
450
|
+
if __name__ == "__main__":
|
|
451
|
+
main()
|