Spaces:
Configuration error
Configuration error
File size: 4,174 Bytes
942b115 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | """Kaggle PaySim dataset download script (SETUP-02).
Downloads the `ealaxi/paysim1` dataset from Kaggle into `data/` and
unzips it so the PaySim CSV lands directly under `data/`.
Note: the dataset originally lived at `ntnu-testimon/paysim1`; that slug now
returns HTTP 403 (dataset moved/retired under the old owner). `ealaxi/paysim1`
is the current live mirror of the same PaySim simulation output (same
~6.36M-row schema: step, type, amount, nameOrig/nameDest, balances, isFraud,
isFlaggedFraud).
Reads `KAGGLE_USERNAME`/`KAGGLE_KEY` from the environment (via `.env`,
loaded with python-dotenv) and fails loud -- naming the missing variable(s)
-- BEFORE attempting any network call or importing the `kaggle` package.
This check must run before `import kaggle`: the installed `kaggle` client
authenticates eagerly as a side effect of importing the package (any
submodule import triggers it), which would otherwise surface its own,
less specific error before our validation ever runs.
Idempotent: if a PaySim CSV already exists under `data/`, the download is
skipped and the existing path is reported.
Usage:
python training/fetch_data.py
"""
from __future__ import annotations
import sys
from pathlib import Path
from dotenv import load_dotenv
DATASET = "ealaxi/paysim1"
DATA_DIR = Path(__file__).resolve().parent.parent / "data"
class FetchDataError(RuntimeError):
"""Raised when the PaySim dataset cannot be fetched.
Messages never include credential values -- only variable names.
"""
def _require_kaggle_credentials() -> None:
"""Fail loud, naming any missing/empty Kaggle credential env var.
Runs before any network call and before `kaggle` is imported.
"""
import os
missing = [
name
for name in ("KAGGLE_USERNAME", "KAGGLE_KEY")
if not os.environ.get(name, "").strip()
]
if missing:
raise FetchDataError(
"Missing required Kaggle credential(s) in the environment: "
f"{', '.join(missing)}. Set them in .env (see README) before "
"running training/fetch_data.py. No network call was made."
)
def _existing_csv() -> Path | None:
if not DATA_DIR.exists():
return None
csvs = sorted(DATA_DIR.glob("*.csv"))
return csvs[0] if csvs else None
def main() -> Path:
load_dotenv()
_require_kaggle_credentials()
existing = _existing_csv()
if existing is not None:
print(f"PaySim CSV already present, skipping download: {existing}")
return existing
# Imported lazily, after credential validation above: importing the
# `kaggle` package (any submodule) triggers its own eager
# authentication check as a side effect of import.
from kaggle.api.kaggle_api_extended import KaggleApi
from requests.exceptions import HTTPError
DATA_DIR.mkdir(parents=True, exist_ok=True)
try:
api = KaggleApi()
api.authenticate()
print(f"Downloading {DATASET} into {DATA_DIR} ...")
api.dataset_download_files(DATASET, path=str(DATA_DIR), unzip=True)
except HTTPError as exc:
status = exc.response.status_code if exc.response is not None else "unknown"
raise FetchDataError(
f"Kaggle API request failed (HTTP {status}) while downloading "
f"'{DATASET}'. This is a Kaggle-side authorization/response "
"issue, not a missing-credential problem -- KAGGLE_USERNAME/"
"KAGGLE_KEY were present and accepted by the auth step. "
"Verify the API token is current (regenerate at "
"https://www.kaggle.com/settings/api if needed) and that the "
"account has access to this dataset."
) from exc
csv_path = _existing_csv()
if csv_path is None:
raise FetchDataError(
f"Download completed but no .csv file was found under {DATA_DIR}. "
"Check the Kaggle dataset contents."
)
print(f"PaySim CSV available at: {csv_path}")
return csv_path
if __name__ == "__main__":
try:
main()
except FetchDataError as exc:
print(f"ERROR: {exc}", file=sys.stderr)
sys.exit(1)
|