Che237 commited on
Commit
d8acf85
·
verified ·
1 Parent(s): 8ffe8e5

Fix cells - make each self-contained with imports

Browse files
Files changed (1) hide show
  1. notebooks/00_environment_setup.ipynb +31 -186
notebooks/00_environment_setup.ipynb CHANGED
@@ -51,23 +51,23 @@
51
  "\n",
52
  "# Python version check\n",
53
  "python_version = sys.version_info\n",
54
- "print(f\"\\n Python Version: {python_version.major}.{python_version.minor}.{python_version.micro}\")\n",
55
  "\n",
56
  "if python_version.major < 3 or (python_version.major == 3 and python_version.minor < 10):\n",
57
  " raise EnvironmentError(\"Python 3.10+ is required. Please upgrade your Python installation.\")\n",
58
  "\n",
59
  "# System info\n",
60
- "print(f\" Platform: {platform.system()} {platform.release()}\")\n",
61
- "print(f\" Architecture: {platform.machine()}\")\n",
62
- "print(f\" Processor: {platform.processor() or 'Unknown'}\")\n",
63
  "\n",
64
  "# Memory info\n",
65
  "try:\n",
66
  " import psutil\n",
67
  " memory = psutil.virtual_memory()\n",
68
- " print(f\" Available Memory: {memory.available / (1024**3):.2f} GB / {memory.total / (1024**3):.2f} GB\")\n",
69
  "except ImportError:\n",
70
- " print(\" psutil not installed - memory check skipped\")\n",
71
  "\n",
72
  "print(\"\\n\" + \"=\" * 60)"
73
  ]
@@ -86,50 +86,7 @@
86
  "id": "faa9b079",
87
  "metadata": {},
88
  "outputs": [],
89
- "source": [
90
- "# Core dependencies with pinned versions for reproducibility\n",
91
- "DEPENDENCIES = \"\"\"\n",
92
- "# Core ML/AI\n",
93
- "numpy>=1.24.0,<2.0.0\n",
94
- "pandas>=2.0.0\n",
95
- "scikit-learn>=1.3.0\n",
96
- "scipy>=1.11.0\n",
97
- "\n",
98
- "# Deep Learning\n",
99
- "torch>=2.0.0\n",
100
- "transformers>=4.30.0\n",
101
- "\n",
102
- "# Gemini API\n",
103
- "google-generativeai>=0.3.0\n",
104
- "\n",
105
- "# Data Processing\n",
106
- "joblib>=1.3.0\n",
107
- "tqdm>=4.65.0\n",
108
- "\n",
109
- "# Feature Engineering\n",
110
- "tldextract>=5.0.0\n",
111
- "validators>=0.22.0\n",
112
- "ipaddress>=1.0.23\n",
113
- "\n",
114
- "# Web/API\n",
115
- "httpx>=0.25.0\n",
116
- "aiohttp>=3.8.0\n",
117
- "requests>=2.31.0\n",
118
- "\n",
119
- "# Hugging Face\n",
120
- "huggingface_hub>=0.19.0\n",
121
- "\n",
122
- "# Utilities\n",
123
- "python-dotenv>=1.0.0\n",
124
- "pyyaml>=6.0.0\n",
125
- "psutil>=5.9.0\n",
126
- "\"\"\"\n",
127
- "\n",
128
- "# Write requirements file\n",
129
- "requirements_path = Path(\"../requirements_notebooks.txt\")\n",
130
- "requirements_path.write_text(DEPENDENCIES.strip())\n",
131
- "print(f\"✓ Requirements written to: {requirements_path.absolute()}\")"
132
- ]
133
  },
134
  {
135
  "cell_type": "code",
@@ -137,22 +94,7 @@
137
  "id": "7dc8c6ca",
138
  "metadata": {},
139
  "outputs": [],
140
- "source": [
141
- "# Install dependencies\n",
142
- "import subprocess\n",
143
- "\n",
144
- "print(\"Installing dependencies... This may take a few minutes.\")\n",
145
- "result = subprocess.run(\n",
146
- " [sys.executable, \"-m\", \"pip\", \"install\", \"-q\", \"-r\", str(requirements_path)],\n",
147
- " capture_output=True,\n",
148
- " text=True\n",
149
- ")\n",
150
- "\n",
151
- "if result.returncode == 0:\n",
152
- " print(\"✓ All dependencies installed successfully!\")\n",
153
- "else:\n",
154
- " print(f\"⚠ Installation warnings: {result.stderr[:500] if result.stderr else 'None'}\")"
155
- ]
156
  },
157
  {
158
  "cell_type": "markdown",
@@ -177,26 +119,26 @@
177
  "\n",
178
  "# Check CUDA availability\n",
179
  "cuda_available = torch.cuda.is_available()\n",
180
- "print(f\"\\n PyTorch Version: {torch.__version__}\")\n",
181
- "print(f\" CUDA Available: {cuda_available}\")\n",
182
  "\n",
183
  "if cuda_available:\n",
184
- " print(f\" CUDA Version: {torch.version.cuda}\")\n",
185
- " print(f\" GPU Count: {torch.cuda.device_count()}\")\n",
186
  " for i in range(torch.cuda.device_count()):\n",
187
  " props = torch.cuda.get_device_properties(i)\n",
188
  " print(f\" - GPU {i}: {props.name} ({props.total_memory / (1024**3):.2f} GB)\")\n",
189
  " DEVICE = torch.device(\"cuda\")\n",
190
  "else:\n",
191
- " print(\" No GPU detected - using CPU for training\")\n",
192
  " DEVICE = torch.device(\"cpu\")\n",
193
  "\n",
194
  "# Check MPS (Apple Silicon)\n",
195
  "if hasattr(torch.backends, 'mps') and torch.backends.mps.is_available():\n",
196
- " print(\" Apple MPS (Metal) available\")\n",
197
  " DEVICE = torch.device(\"mps\")\n",
198
  "\n",
199
- "print(f\"\\n Selected Device: {DEVICE}\")\n",
200
  "print(\"=\" * 60)"
201
  ]
202
  },
@@ -214,67 +156,7 @@
214
  "id": "0f63a5ce",
215
  "metadata": {},
216
  "outputs": [],
217
- "source": [
218
- "import json\n",
219
- "import os\n",
220
- "from pathlib import Path\n",
221
- "\n",
222
- "# Load configuration from notebook_config.json first (for HF Spaces)\n",
223
- "config_json_path = Path(\"notebook_config.json\")\n",
224
- "if config_json_path.exists():\n",
225
- " with open(config_json_path, \"r\") as f:\n",
226
- " loaded_config = json.load(f)\n",
227
- " print(f\"✓ Loaded configuration from: {config_json_path.absolute()}\")\n",
228
- "else:\n",
229
- " loaded_config = {}\n",
230
- " print(f\"⚠ No notebook_config.json found, using defaults\")\n",
231
- "\n",
232
- "# Try loading .env file as fallback (for local dev)\n",
233
- "try:\n",
234
- " from dotenv import load_dotenv\n",
235
- " env_path = Path(\"../.env\")\n",
236
- " if env_path.exists():\n",
237
- " load_dotenv(env_path)\n",
238
- " print(f\"✓ Loaded environment from: {env_path.absolute()}\")\n",
239
- "except ImportError:\n",
240
- " pass\n",
241
- "\n",
242
- "# Configuration class\n",
243
- "class Config:\n",
244
- " # API Keys - priority: config.json > env vars > HF secrets\n",
245
- " GEMINI_API_KEY = loaded_config.get(\"gemini_api_key\") or os.getenv(\"GEMINI_API_KEY\", \"AIzaSyA3HdWTLk_zJQ5P9G8Z8a8BEYSTPvLglhs\")\n",
246
- " HUGGINGFACE_TOKEN = os.getenv(\"HUGGINGFACE_API_TOKEN\", os.getenv(\"HF_TOKEN\", \"\"))\n",
247
- " WEBSCRAPER_API_KEY = loaded_config.get(\"webscraper_api_key\", \"sk-fd14eaa7bceb478db7afc7256e514d2b\")\n",
248
- " WEBSCRAPER_API_URL = loaded_config.get(\"webscraper_api_url\", \"http://webscrapper.live/api/scrape\")\n",
249
- " \n",
250
- " # Gemini model\n",
251
- " GEMINI_MODEL = loaded_config.get(\"gemini_model\", \"gemini-2.5-flash\")\n",
252
- " \n",
253
- " # Paths\n",
254
- " BASE_DIR = Path(\"..\").resolve()\n",
255
- " DATASETS_DIR = BASE_DIR / \"datasets\"\n",
256
- " MODELS_DIR = BASE_DIR / \"models\"\n",
257
- " ARTIFACTS_DIR = BASE_DIR / \"artifacts\"\n",
258
- " \n",
259
- " # ML Settings\n",
260
- " RANDOM_STATE = loaded_config.get(\"random_state\", 42)\n",
261
- " TEST_SIZE = loaded_config.get(\"test_size\", 0.2)\n",
262
- " CV_FOLDS = loaded_config.get(\"cv_folds\", 5)\n",
263
- " \n",
264
- " # Device\n",
265
- " DEVICE = DEVICE\n",
266
- "\n",
267
- "config = Config()\n",
268
- "\n",
269
- "# Validate required API keys\n",
270
- "print(\"\\n\" + \"=\" * 60)\n",
271
- "print(\"API CONFIGURATION STATUS\")\n",
272
- "print(\"=\" * 60)\n",
273
- "print(f\"✓ Gemini API Key: {'Configured (' + config.GEMINI_API_KEY[:10] + '...)' if config.GEMINI_API_KEY else '⚠ NOT SET'}\")\n",
274
- "print(f\"✓ Gemini Model: {config.GEMINI_MODEL}\")\n",
275
- "print(f\"✓ HuggingFace Token: {'Configured' if config.HUGGINGFACE_TOKEN else '⚠ NOT SET (optional)'}\")\n",
276
- "print(f\"✓ WebScraper API: Configured\")"
277
- ]
278
  },
279
  {
280
  "cell_type": "markdown",
@@ -317,9 +199,9 @@
317
  "success, message = test_gemini_connection()\n",
318
  "\n",
319
  "if success:\n",
320
- " print(f\" Gemini API: {message}\")\n",
321
  "else:\n",
322
- " print(f\" Gemini API: Connection failed - {message}\")"
323
  ]
324
  },
325
  {
@@ -336,44 +218,7 @@
336
  "id": "beb1b036",
337
  "metadata": {},
338
  "outputs": [],
339
- "source": [
340
- "import httpx\n",
341
- "import asyncio\n",
342
- "\n",
343
- "# Install nest_asyncio for Jupyter compatibility\n",
344
- "try:\n",
345
- " import nest_asyncio\n",
346
- " nest_asyncio.apply()\n",
347
- "except ImportError:\n",
348
- " pass # Will use synchronous fallback\n",
349
- "\n",
350
- "def test_webscraper_connection_sync():\n",
351
- " \"\"\"Test WebScrapper.live API connectivity (sync version)\"\"\"\n",
352
- " try:\n",
353
- " with httpx.Client(timeout=30.0) as client:\n",
354
- " response = client.post(\n",
355
- " config.WEBSCRAPER_API_URL,\n",
356
- " json={\"url\": \"https://example.com\"},\n",
357
- " headers={\n",
358
- " \"Content-Type\": \"application/json\",\n",
359
- " \"X-API-Key\": config.WEBSCRAPER_API_KEY\n",
360
- " }\n",
361
- " )\n",
362
- " if response.status_code == 200:\n",
363
- " return True, \"Connected\"\n",
364
- " else:\n",
365
- " return False, f\"Status {response.status_code}: {response.text[:100]}\"\n",
366
- " except Exception as e:\n",
367
- " return False, str(e)\n",
368
- "\n",
369
- "print(\"Testing Web Scraper API connection...\")\n",
370
- "success, message = test_webscraper_connection_sync()\n",
371
- "\n",
372
- "if success:\n",
373
- " print(f\"✓ WebScraper API: Connected successfully\")\n",
374
- "else:\n",
375
- " print(f\"⚠ WebScraper API: {message}\")"
376
- ]
377
  },
378
  {
379
  "cell_type": "markdown",
@@ -402,9 +247,9 @@
402
  "print(\"Creating directory structure...\")\n",
403
  "for directory in directories:\n",
404
  " directory.mkdir(parents=True, exist_ok=True)\n",
405
- " print(f\" {directory}\")\n",
406
  "\n",
407
- "print(\"\\n Directory structure ready!\")"
408
  ]
409
  },
410
  {
@@ -446,7 +291,7 @@
446
  "with open(config_path, \"w\") as f:\n",
447
  " json.dump(notebook_config, f, indent=2)\n",
448
  "\n",
449
- "print(f\" Configuration saved to: {config_path}\")\n",
450
  "print(\"\\n\" + json.dumps(notebook_config, indent=2))"
451
  ]
452
  },
@@ -469,16 +314,16 @@
469
  "print(\"ENVIRONMENT SETUP COMPLETE\")\n",
470
  "print(\"=\" * 60)\n",
471
  "print(f\"\"\"\n",
472
- " Python: {python_version.major}.{python_version.minor}.{python_version.micro}\n",
473
- " Device: {DEVICE}\n",
474
- " PyTorch: {torch.__version__}\n",
475
- " Gemini API: {'Ready' if config.GEMINI_API_KEY else 'Not configured'}\n",
476
- " HuggingFace: {'Ready' if config.HUGGINGFACE_TOKEN else 'Not configured'}\n",
477
- " WebScraper API: Ready\n",
478
- " Directories: Created\n",
479
  "\n",
480
  "You can now proceed to the next notebook:\n",
481
- " 01_data_acquisition.ipynb\n",
482
  "\"\"\")\n",
483
  "print(\"=\" * 60)"
484
  ]
@@ -491,4 +336,4 @@
491
  },
492
  "nbformat": 4,
493
  "nbformat_minor": 5
494
- }
 
51
  "\n",
52
  "# Python version check\n",
53
  "python_version = sys.version_info\n",
54
+ "print(f\"\\n\u2713 Python Version: {python_version.major}.{python_version.minor}.{python_version.micro}\")\n",
55
  "\n",
56
  "if python_version.major < 3 or (python_version.major == 3 and python_version.minor < 10):\n",
57
  " raise EnvironmentError(\"Python 3.10+ is required. Please upgrade your Python installation.\")\n",
58
  "\n",
59
  "# System info\n",
60
+ "print(f\"\u2713 Platform: {platform.system()} {platform.release()}\")\n",
61
+ "print(f\"\u2713 Architecture: {platform.machine()}\")\n",
62
+ "print(f\"\u2713 Processor: {platform.processor() or 'Unknown'}\")\n",
63
  "\n",
64
  "# Memory info\n",
65
  "try:\n",
66
  " import psutil\n",
67
  " memory = psutil.virtual_memory()\n",
68
+ " print(f\"\u2713 Available Memory: {memory.available / (1024**3):.2f} GB / {memory.total / (1024**3):.2f} GB\")\n",
69
  "except ImportError:\n",
70
+ " print(\"\u26a0 psutil not installed - memory check skipped\")\n",
71
  "\n",
72
  "print(\"\\n\" + \"=\" * 60)"
73
  ]
 
86
  "id": "faa9b079",
87
  "metadata": {},
88
  "outputs": [],
89
+ "source": "from pathlib import Path\n\n# Core dependencies with pinned versions for reproducibility\nDEPENDENCIES = \"\"\"\n# Core ML/AI\nnumpy>=1.24.0,<2.0.0\npandas>=2.0.0\nscikit-learn>=1.3.0\nscipy>=1.11.0\n\n# Deep Learning \ntorch>=2.0.0\ntransformers>=4.30.0\n\n# Gemini API\ngoogle-generativeai>=0.3.0\n\n# Data Processing\njoblib>=1.3.0\ntqdm>=4.65.0\n\n# Feature Engineering\ntldextract>=5.0.0\nvalidators>=0.22.0\n\n# Web/API\nhttpx>=0.25.0\nrequests>=2.31.0\n\n# Hugging Face\nhuggingface_hub>=0.19.0\n\n# Utilities\npython-dotenv>=1.0.0\npyyaml>=6.0.0\npsutil>=5.9.0\n\"\"\"\n\n# Write requirements file\nrequirements_path = Path(\"../requirements_notebooks.txt\")\nrequirements_path.write_text(DEPENDENCIES.strip())\nprint(f\"\u2713 Requirements written to: {requirements_path.absolute()}\")\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  },
91
  {
92
  "cell_type": "code",
 
94
  "id": "7dc8c6ca",
95
  "metadata": {},
96
  "outputs": [],
97
+ "source": "import subprocess\nimport sys\nfrom pathlib import Path\n\n# Install dependencies\nrequirements_path = Path(\"../requirements_notebooks.txt\")\n\nif requirements_path.exists():\n print(\"Installing dependencies... This may take a few minutes.\")\n result = subprocess.run(\n [sys.executable, \"-m\", \"pip\", \"install\", \"-q\", \"-r\", str(requirements_path)],\n capture_output=True,\n text=True\n )\n\n if result.returncode == 0:\n print(\"\u2713 All dependencies installed successfully!\")\n else:\n print(f\"\u26a0 Installation warnings: {result.stderr[:500] if result.stderr else 'None'}\")\nelse:\n print(\"\u26a0 Requirements file not found. Run previous cell first or skip if deps installed.\")\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98
  },
99
  {
100
  "cell_type": "markdown",
 
119
  "\n",
120
  "# Check CUDA availability\n",
121
  "cuda_available = torch.cuda.is_available()\n",
122
+ "print(f\"\\n\u2713 PyTorch Version: {torch.__version__}\")\n",
123
+ "print(f\"\u2713 CUDA Available: {cuda_available}\")\n",
124
  "\n",
125
  "if cuda_available:\n",
126
+ " print(f\"\u2713 CUDA Version: {torch.version.cuda}\")\n",
127
+ " print(f\"\u2713 GPU Count: {torch.cuda.device_count()}\")\n",
128
  " for i in range(torch.cuda.device_count()):\n",
129
  " props = torch.cuda.get_device_properties(i)\n",
130
  " print(f\" - GPU {i}: {props.name} ({props.total_memory / (1024**3):.2f} GB)\")\n",
131
  " DEVICE = torch.device(\"cuda\")\n",
132
  "else:\n",
133
+ " print(\"\u26a0 No GPU detected - using CPU for training\")\n",
134
  " DEVICE = torch.device(\"cpu\")\n",
135
  "\n",
136
  "# Check MPS (Apple Silicon)\n",
137
  "if hasattr(torch.backends, 'mps') and torch.backends.mps.is_available():\n",
138
+ " print(\"\u2713 Apple MPS (Metal) available\")\n",
139
  " DEVICE = torch.device(\"mps\")\n",
140
  "\n",
141
+ "print(f\"\\n\u2713 Selected Device: {DEVICE}\")\n",
142
  "print(\"=\" * 60)"
143
  ]
144
  },
 
156
  "id": "0f63a5ce",
157
  "metadata": {},
158
  "outputs": [],
159
+ "source": "import json\nimport os\nfrom pathlib import Path\n\n# Load configuration from notebook_config.json first (for HF Spaces)\nconfig_json_path = Path(\"notebook_config.json\")\nif config_json_path.exists():\n with open(config_json_path, \"r\") as f:\n loaded_config = json.load(f)\n print(f\"\u2713 Loaded configuration from: {config_json_path.absolute()}\")\nelse:\n loaded_config = {}\n print(f\"\u26a0 No notebook_config.json found, using defaults\")\n\n# Try loading .env file as fallback (for local dev)\ntry:\n from dotenv import load_dotenv\n env_path = Path(\"../.env\")\n if env_path.exists():\n load_dotenv(env_path)\n print(f\"\u2713 Loaded environment from: {env_path.absolute()}\")\nexcept ImportError:\n pass\n\n# Detect device\ntry:\n import torch\n if torch.cuda.is_available():\n DEVICE = torch.device(\"cuda\")\n elif hasattr(torch.backends, 'mps') and torch.backends.mps.is_available():\n DEVICE = torch.device(\"mps\")\n else:\n DEVICE = torch.device(\"cpu\")\nexcept ImportError:\n DEVICE = \"cpu\"\n\n# Configuration class\nclass Config:\n # API Keys - priority: config.json > env vars > defaults\n GEMINI_API_KEY = loaded_config.get(\"gemini_api_key\") or os.getenv(\"GEMINI_API_KEY\", \"AIzaSyA3HdWTLk_zJQ5P9G8Z8a8BEYSTPvLglhs\")\n HUGGINGFACE_TOKEN = os.getenv(\"HUGGINGFACE_API_TOKEN\", os.getenv(\"HF_TOKEN\", \"\"))\n WEBSCRAPER_API_KEY = loaded_config.get(\"webscraper_api_key\", \"sk-fd14eaa7bceb478db7afc7256e514d2b\")\n WEBSCRAPER_API_URL = loaded_config.get(\"webscraper_api_url\", \"http://webscrapper.live/api/scrape\")\n \n # Gemini model\n GEMINI_MODEL = loaded_config.get(\"gemini_model\", \"gemini-2.5-flash\")\n \n # Paths\n BASE_DIR = Path(\"..\").resolve()\n DATASETS_DIR = BASE_DIR / \"datasets\"\n MODELS_DIR = BASE_DIR / \"models\"\n ARTIFACTS_DIR = BASE_DIR / \"artifacts\"\n \n # ML Settings\n RANDOM_STATE = loaded_config.get(\"random_state\", 42)\n TEST_SIZE = loaded_config.get(\"test_size\", 0.2)\n CV_FOLDS = loaded_config.get(\"cv_folds\", 5)\n \n # Device\n DEVICE = DEVICE\n\nconfig = Config()\n\n# Validate required API keys\nprint(\"\\n\" + \"=\" * 60)\nprint(\"API CONFIGURATION STATUS\")\nprint(\"=\" * 60)\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
160
  },
161
  {
162
  "cell_type": "markdown",
 
199
  "success, message = test_gemini_connection()\n",
200
  "\n",
201
  "if success:\n",
202
+ " print(f\"\u2713 Gemini API: {message}\")\n",
203
  "else:\n",
204
+ " print(f\"\u26a0 Gemini API: Connection failed - {message}\")"
205
  ]
206
  },
207
  {
 
218
  "id": "beb1b036",
219
  "metadata": {},
220
  "outputs": [],
221
+ "source": "import httpx\n\ndef test_webscraper_connection_sync():\n \"\"\"Test WebScrapper.live API connectivity (sync version)\"\"\"\n try:\n with httpx.Client(timeout=30.0) as client:\n response = client.post(\n config.WEBSCRAPER_API_URL,\n json={\"url\": \"https://example.com\"},\n headers={\n \"Content-Type\": \"application/json\",\n \"X-API-Key\": config.WEBSCRAPER_API_KEY\n }\n )\n if response.status_code == 200:\n return True, \"Connected\"\n else:\n return False, f\"Status {response.status_code}: {response.text[:100]}\"\n except Exception as e:\n return False, str(e)\n\nprint(\"Testing Web Scraper API connection...\")\nsuccess, message = test_webscraper_connection_sync()\n\nif success:\n print(f\"\u2713 WebScraper API: Connected successfully\")\nelse:\n print(f\"\u26a0 WebScraper API: {message}\")\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
222
  },
223
  {
224
  "cell_type": "markdown",
 
247
  "print(\"Creating directory structure...\")\n",
248
  "for directory in directories:\n",
249
  " directory.mkdir(parents=True, exist_ok=True)\n",
250
+ " print(f\" \u2713 {directory}\")\n",
251
  "\n",
252
+ "print(\"\\n\u2713 Directory structure ready!\")"
253
  ]
254
  },
255
  {
 
291
  "with open(config_path, \"w\") as f:\n",
292
  " json.dump(notebook_config, f, indent=2)\n",
293
  "\n",
294
+ "print(f\"\u2713 Configuration saved to: {config_path}\")\n",
295
  "print(\"\\n\" + json.dumps(notebook_config, indent=2))"
296
  ]
297
  },
 
314
  "print(\"ENVIRONMENT SETUP COMPLETE\")\n",
315
  "print(\"=\" * 60)\n",
316
  "print(f\"\"\"\n",
317
+ "\u2705 Python: {python_version.major}.{python_version.minor}.{python_version.micro}\n",
318
+ "\u2705 Device: {DEVICE}\n",
319
+ "\u2705 PyTorch: {torch.__version__}\n",
320
+ "\u2705 Gemini API: {'Ready' if config.GEMINI_API_KEY else 'Not configured'}\n",
321
+ "\u2705 HuggingFace: {'Ready' if config.HUGGINGFACE_TOKEN else 'Not configured'}\n",
322
+ "\u2705 WebScraper API: Ready\n",
323
+ "\u2705 Directories: Created\n",
324
  "\n",
325
  "You can now proceed to the next notebook:\n",
326
+ " \u2192 01_data_acquisition.ipynb\n",
327
  "\"\"\")\n",
328
  "print(\"=\" * 60)"
329
  ]
 
336
  },
337
  "nbformat": 4,
338
  "nbformat_minor": 5
339
+ }