{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "a8de14bc",
   "metadata": {},
   "source": [
    "# filoma — Quick interactive examples\n",
    "\n",
    "This notebook demonstrates key filoma capabilities and includes lightweight checks to see if it works in your environment.\n",
    "\n",
    "It covers: imports and version checks, probing a file and a directory, working with the `filoma.DataFrame` wrapper, using `probe_to_df`, a small image probe example, and saving a CSV export.\n",
    "\n",
    "Note: cells wrap operations in `try/except` so the notebook still runs if optional dependencies (e.g. `polars`, `numpy`, or image backends) are missing."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "1f1acab5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'filoma': '1.7.6',\n",
       " 'polars': 'available',\n",
       " 'numpy': 'available',\n",
       " 'PIL': 'available',\n",
       " 'cwd': '/home/kalfasy/repos/filoma/notebooks'}"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Basic environment and import checks\n",
    "from pathlib import Path\n",
    "\n",
    "import filoma\n",
    "from filoma import DataFrame\n",
    "\n",
    "\n",
    "def check_imports():\n",
    "    results = {}\n",
    "    try:\n",
    "        import filoma\n",
    "\n",
    "        results[\"filoma\"] = getattr(filoma, \"__version__\", \"unknown\")\n",
    "    except Exception as e:\n",
    "        results[\"filoma\"] = f\"IMPORT ERROR: {e}\"\n",
    "\n",
    "    for pkg in (\"polars\", \"numpy\", \"PIL\"):\n",
    "        try:\n",
    "            __import__(pkg if pkg != \"PIL\" else \"PIL.Image\")\n",
    "            results[pkg] = \"available\"\n",
    "        except Exception as e:\n",
    "            results[pkg] = f\"missing ({e})\"\n",
    "\n",
    "    # show where we are running the notebook from\n",
    "    results[\"cwd\"] = str(Path(\".\").resolve())\n",
    "    return results\n",
    "\n",
    "\n",
    "check_imports()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5492a20b",
   "metadata": {},
   "source": [
    "## 1) Quick probe: a single file and a directory\n",
    "\n",
    "Try probing a README or small file, then probe a lightweight sample directory from the repo's `tests/` tree."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "623b0d1e",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\u001b[32m2025-09-20 21:43:20.513\u001b[0m | \u001b[34m\u001b[1mDEBUG   \u001b[0m | \u001b[36mfiloma.directories.directory_profiler\u001b[0m:\u001b[36m__init__\u001b[0m:\u001b[36m352\u001b[0m - \u001b[34m\u001b[1mInteractive environment detected, disabling progress bars to avoid conflicts\u001b[0m\n",
      "\u001b[32m2025-09-20 21:43:20.513\u001b[0m | \u001b[1mINFO    \u001b[0m | \u001b[36mfiloma.directories.directory_profiler\u001b[0m:\u001b[36mprobe\u001b[0m:\u001b[36m439\u001b[0m - \u001b[1mStarting directory analysis of '../tests/' using 🦀 Rust (Parallel) implementation\u001b[0m\n",
      "\u001b[32m2025-09-20 21:43:20.515\u001b[0m | \u001b[32m\u001b[1mSUCCESS \u001b[0m | \u001b[36mfiloma.directories.directory_profiler\u001b[0m:\u001b[36mprobe\u001b[0m:\u001b[36m455\u001b[0m - \u001b[32m\u001b[1mDirectory analysis completed in 0.00s - Found 179 items (154 files, 25 folders) using 🦀 Rust (Parallel)\u001b[0m\n",
      "\u001b[32m2025-09-20 21:43:20.515\u001b[0m | \u001b[33m\u001b[1mWARNING \u001b[0m | \u001b[36mfiloma.directories.directory_profiler\u001b[0m:\u001b[36mto_df\u001b[0m:\u001b[36m193\u001b[0m - \u001b[33m\u001b[1mNo DataFrame available for analysis at path /home/kalfasy/repos/filoma/tests. DataFrame building is disabled by default or 'polars' is not installed. Call DirectoryProfiler(build_dataframe=True) or use filoma.probe_to_df(...) to obtain a DataFrame.\u001b[0m\n",
      "\u001b[32m2025-09-20 21:43:20.513\u001b[0m | \u001b[1mINFO    \u001b[0m | \u001b[36mfiloma.directories.directory_profiler\u001b[0m:\u001b[36mprobe\u001b[0m:\u001b[36m439\u001b[0m - \u001b[1mStarting directory analysis of '../tests/' using 🦀 Rust (Parallel) implementation\u001b[0m\n",
      "\u001b[32m2025-09-20 21:43:20.515\u001b[0m | \u001b[32m\u001b[1mSUCCESS \u001b[0m | \u001b[36mfiloma.directories.directory_profiler\u001b[0m:\u001b[36mprobe\u001b[0m:\u001b[36m455\u001b[0m - \u001b[32m\u001b[1mDirectory analysis completed in 0.00s - Found 179 items (154 files, 25 folders) using 🦀 Rust (Parallel)\u001b[0m\n",
      "\u001b[32m2025-09-20 21:43:20.515\u001b[0m | \u001b[33m\u001b[1mWARNING \u001b[0m | \u001b[36mfiloma.directories.directory_profiler\u001b[0m:\u001b[36mto_df\u001b[0m:\u001b[36m193\u001b[0m - \u001b[33m\u001b[1mNo DataFrame available for analysis at path /home/kalfasy/repos/filoma/tests. DataFrame building is disabled by default or 'polars' is not installed. Call DirectoryProfiler(build_dataframe=True) or use filoma.probe_to_df(...) to obtain a DataFrame.\u001b[0m\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "probing file -> ../README.md\n",
      "file probe result type: <class 'filoma.files.file_profiler.Filo'>\n",
      "Filo(path=PosixPath('/home/kalfasy/repos/filoma/README.md'), size=6413, mode='0o100664', mode_str='-rw-rw-r--', owner='kalfasy', group='kalfasy', created=datetime.datetime(2025, 9, 20, 0, 24, 52), modified=datetime.datetime(2025, 9, 20, 0, 24, 52), accessed=datetime.datetime(2025, 9, 20, 0, 24, 52), is_symlink=False, is_file=True, is_dir=False, target_is_file=None, target_is_dir=None, rights={'read': True, 'write': True, 'execute': False}, inode=7601600, nlink=1, sha256=None, xattrs={})\n",
      "probing directory -> ../tests/\n",
      "directory probe returned an object of type: <class 'filoma.directories.directory_profiler.DirectoryAnalysis'>\n",
      "to_df() -> wrapper type: <class 'NoneType'>\n"
     ]
    }
   ],
   "source": [
    "file_candidate = \"../README.md\"\n",
    "dir_candidate = \"../tests/\"\n",
    "\n",
    "print(\"probing file ->\", file_candidate)\n",
    "if file_candidate is not None:\n",
    "    try:\n",
    "        file_report = filoma.probe(file_candidate)\n",
    "        print(\"file probe result type:\", type(file_report))\n",
    "        try:\n",
    "            # many filoma dataclasses implement a nice repr or to-dict\n",
    "            print(file_report)\n",
    "        except Exception:\n",
    "            pass\n",
    "    except Exception as e:\n",
    "        print(\"file probe failed:\", e)\n",
    "else:\n",
    "    print(\"No small file found to probe in the repository root.\")\n",
    "\n",
    "print(\"probing directory ->\", dir_candidate)\n",
    "if dir_candidate is not None:\n",
    "    try:\n",
    "        dir_report = filoma.probe(dir_candidate, max_depth=2, threads=2)\n",
    "        print(\"directory probe returned an object of type:\", type(dir_report))\n",
    "        # If it exposes a to_df() method we can inspect a little\n",
    "        if hasattr(dir_report, \"to_df\"):\n",
    "            try:\n",
    "                dfw = dir_report.to_df()\n",
    "                print(\"to_df() -> wrapper type:\", type(dfw))\n",
    "            except Exception as e:\n",
    "                print(\"to_df() raised:\", e)\n",
    "    except Exception as e:\n",
    "        print(\"directory probe failed:\", e)\n",
    "else:\n",
    "    print(\"No small directory found to probe in tests/; adjust the path and re-run.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6762e273",
   "metadata": {},
   "source": [
    "## 2) Working with `filoma.DataFrame` wrapper\n",
    "\n",
    "Construct a `filoma.DataFrame` from a list of paths and run the convenience enrichers: `.add_path_components()`, `.add_file_stats_cols()`, and `.add_depth_col()`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "57537daa",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "sample paths used: [PosixPath('../README.md'), PosixPath('../pyproject.toml'), PosixPath('../Cargo.toml')]\n",
      "Initial wrapper and head:\n",
      "filoma.DataFrame with 3 rows\n",
      "shape: (3, 1)\n",
      "┌───────────────────┐\n",
      "│ path              │\n",
      "│ ---               │\n",
      "│ str               │\n",
      "╞═══════════════════╡\n",
      "│ ../README.md      │\n",
      "│ ../pyproject.toml │\n",
      "│ ../Cargo.toml     │\n",
      "└───────────────────┘\n",
      "With path components:\n",
      "filoma.DataFrame with 3 rows\n",
      "shape: (3, 5)\n",
      "┌───────────────────┬────────┬────────────────┬───────────┬────────┐\n",
      "│ path              ┆ parent ┆ name           ┆ stem      ┆ suffix │\n",
      "│ ---               ┆ ---    ┆ ---            ┆ ---       ┆ ---    │\n",
      "│ str               ┆ str    ┆ str            ┆ str       ┆ str    │\n",
      "╞═══════════════════╪════════╪════════════════╪═══════════╪════════╡\n",
      "│ ../README.md      ┆ ..     ┆ README.md      ┆ README    ┆ .md    │\n",
      "│ ../pyproject.toml ┆ ..     ┆ pyproject.toml ┆ pyproject ┆ .toml  │\n",
      "│ ../Cargo.toml     ┆ ..     ┆ Cargo.toml     ┆ Cargo     ┆ .toml  │\n",
      "└───────────────────┴────────┴────────────────┴───────────┴────────┘\n",
      "With file stats:\n",
      "filoma.DataFrame with 3 rows\n",
      "shape: (3, 13)\n",
      "┌───────────────┬────────────┬──────────────┬──────────────┬───┬─────────┬───────┬────────┬────────┐\n",
      "│ path          ┆ size_bytes ┆ modified_tim ┆ created_time ┆ … ┆ inode   ┆ nlink ┆ sha256 ┆ xattrs │\n",
      "│ ---           ┆ ---        ┆ e            ┆ ---          ┆   ┆ ---     ┆ ---   ┆ ---    ┆ ---    │\n",
      "│ str           ┆ i64        ┆ ---          ┆ str          ┆   ┆ i64     ┆ i64   ┆ str    ┆ str    │\n",
      "│               ┆            ┆ str          ┆              ┆   ┆         ┆       ┆        ┆        │\n",
      "╞═══════════════╪════════════╪══════════════╪══════════════╪═══╪═════════╪═══════╪════════╪════════╡\n",
      "│ ../README.md  ┆ 6413       ┆ 2025-09-20   ┆ 2025-09-20   ┆ … ┆ 7601600 ┆ 1     ┆ null   ┆ {}     │\n",
      "│               ┆            ┆ 00:24:52     ┆ 00:24:52     ┆   ┆         ┆       ┆        ┆        │\n",
      "│ ../pyproject. ┆ 2113       ┆ 2025-09-20   ┆ 2025-09-20   ┆ … ┆ 7579961 ┆ 1     ┆ null   ┆ {}     │\n",
      "│ toml          ┆            ┆ 21:39:44     ┆ 21:39:44     ┆   ┆         ┆       ┆        ┆        │\n",
      "│ ../Cargo.toml ┆ 481        ┆ 2025-08-30   ┆ 2025-08-30   ┆ … ┆ 7579934 ┆ 1     ┆ null   ┆ {}     │\n",
      "│               ┆            ┆ 20:14:29     ┆ 20:14:29     ┆   ┆         ┆       ┆        ┆        │\n",
      "└───────────────┴────────────┴──────────────┴──────────────┴───┴─────────┴───────┴────────┴────────┘\n",
      "Add depth column relative to repo root:\n",
      "filoma.DataFrame with 3 rows\n",
      "shape: (3, 2)\n",
      "┌───────────────────┬───────┐\n",
      "│ path              ┆ depth │\n",
      "│ ---               ┆ ---   │\n",
      "│ str               ┆ i64   │\n",
      "╞═══════════════════╪═══════╡\n",
      "│ ../README.md      ┆ 2     │\n",
      "│ ../pyproject.toml ┆ 2     │\n",
      "│ ../Cargo.toml     ┆ 2     │\n",
      "└───────────────────┴───────┘\n"
     ]
    }
   ],
   "source": [
    "sample_paths = [p for p in (Path(\"../README.md\"), Path(\"../pyproject.toml\"), Path(\"../Cargo.toml\")) if p.exists()]\n",
    "if not sample_paths:\n",
    "    # fallback to a couple of files from tests if present\n",
    "    sample_paths = [p for p in (Path(\"../tests/test_basic_dataframe.py\"), Path(\"../tests/test_rust_comprehensive.py\")) if p.exists()]\n",
    "\n",
    "print(\"sample paths used:\", sample_paths)\n",
    "dfw = DataFrame(sample_paths)\n",
    "print(\"Initial wrapper and head:\")\n",
    "print(dfw.head(10))\n",
    "\n",
    "print(\"With path components:\")\n",
    "try:\n",
    "    df_components = dfw.add_path_components()\n",
    "    print(df_components.head(10))\n",
    "except Exception as e:\n",
    "    print(\"add_path_components failed:\", e)\n",
    "\n",
    "print(\"With file stats:\")\n",
    "try:\n",
    "    df_stats = dfw.add_file_stats_cols()\n",
    "    print(df_stats.head(10))\n",
    "except Exception as e:\n",
    "    print(\"add_file_stats_cols failed:\", e)\n",
    "\n",
    "print(\"Add depth column relative to repo root:\")\n",
    "try:\n",
    "    df_depth = dfw.add_depth_col(Path(\".\"))\n",
    "    print(df_depth.head(10))\n",
    "except Exception as e:\n",
    "    print(\"add_depth_col failed:\", e)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "73602797",
   "metadata": {},
   "source": [
    "## 3) Build a DataFrame from a directory using `probe_to_df`\n",
    "\n",
    "This uses filoma's convenience `probe_to_df` which returns a `filoma.DataFrame` wrapper (Polars is used internally if available). We request a lightweight folder under `tests/` to keep runtime small."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "883738ea",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\u001b[32m2025-09-20 21:43:20.530\u001b[0m | \u001b[34m\u001b[1mDEBUG   \u001b[0m | \u001b[36mfiloma.directories.directory_profiler\u001b[0m:\u001b[36m__init__\u001b[0m:\u001b[36m352\u001b[0m - \u001b[34m\u001b[1mInteractive environment detected, disabling progress bars to avoid conflicts\u001b[0m\n",
      "\u001b[32m2025-09-20 21:43:20.531\u001b[0m | \u001b[1mINFO    \u001b[0m | \u001b[36mfiloma.directories.directory_profiler\u001b[0m:\u001b[36mprobe\u001b[0m:\u001b[36m439\u001b[0m - \u001b[1mStarting directory analysis of '../tests' using 🦀 Rust (Parallel) implementation\u001b[0m\n",
      "\u001b[32m2025-09-20 21:43:20.534\u001b[0m | \u001b[32m\u001b[1mSUCCESS \u001b[0m | \u001b[36mfiloma.directories.directory_profiler\u001b[0m:\u001b[36mprobe\u001b[0m:\u001b[36m455\u001b[0m - \u001b[32m\u001b[1mDirectory analysis completed in 0.00s - Found 179 items (154 files, 25 folders) using 🦀 Rust (Parallel)\u001b[0m\n",
      "\u001b[32m2025-09-20 21:43:20.531\u001b[0m | \u001b[1mINFO    \u001b[0m | \u001b[36mfiloma.directories.directory_profiler\u001b[0m:\u001b[36mprobe\u001b[0m:\u001b[36m439\u001b[0m - \u001b[1mStarting directory analysis of '../tests' using 🦀 Rust (Parallel) implementation\u001b[0m\n",
      "\u001b[32m2025-09-20 21:43:20.534\u001b[0m | \u001b[32m\u001b[1mSUCCESS \u001b[0m | \u001b[36mfiloma.directories.directory_profiler\u001b[0m:\u001b[36mprobe\u001b[0m:\u001b[36m455\u001b[0m - \u001b[32m\u001b[1mDirectory analysis completed in 0.00s - Found 179 items (154 files, 25 folders) using 🦀 Rust (Parallel)\u001b[0m\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "probe_to_df returned a filoma.DataFrame with shape: (146, 18)\n",
      "Sample rows:\n",
      "filoma.DataFrame with 5 rows\n",
      "shape: (5, 18)\n",
      "┌───────────────────┬───────┬──────────┬──────────────────┬───┬──────────┬───────┬────────┬────────┐\n",
      "│ path              ┆ depth ┆ parent   ┆ name             ┆ … ┆ inode    ┆ nlink ┆ sha256 ┆ xattrs │\n",
      "│ ---               ┆ ---   ┆ ---      ┆ ---              ┆   ┆ ---      ┆ ---   ┆ ---    ┆ ---    │\n",
      "│ str               ┆ i64   ┆ str      ┆ str              ┆   ┆ i64      ┆ i64   ┆ str    ┆ str    │\n",
      "╞═══════════════════╪═══════╪══════════╪══════════════════╪═══╪══════════╪═══════╪════════╪════════╡\n",
      "│ ../tests/test_asy ┆ 1     ┆ ../tests ┆ test_async_rust_ ┆ … ┆ 7601345  ┆ 1     ┆ null   ┆ {}     │\n",
      "│ nc_rust_extra…    ┆       ┆          ┆ extra.py         ┆   ┆          ┆       ┆        ┆        │\n",
      "│ ../tests/test_bas ┆ 1     ┆ ../tests ┆ test_basic_dataf ┆ … ┆ 7602664  ┆ 1     ┆ null   ┆ {}     │\n",
      "│ ic_dataframe.…    ┆       ┆          ┆ rame.py          ┆   ┆          ┆       ┆        ┆        │\n",
      "│ ../tests/scripts  ┆ 1     ┆ ../tests ┆ scripts          ┆ … ┆ 13593175 ┆ 3     ┆ null   ┆ {}     │\n",
      "│ ../tests/test_ml_ ┆ 1     ┆ ../tests ┆ test_ml_core.py  ┆ … ┆ 7602966  ┆ 1     ┆ null   ┆ {}     │\n",
      "│ core.py           ┆       ┆          ┆                  ┆   ┆          ┆       ┆        ┆        │\n",
      "│ ../tests/test_rus ┆ 1     ┆ ../tests ┆ test_rust_absolu ┆ … ┆ 7601819  ┆ 1     ┆ null   ┆ {}     │\n",
      "│ t_absolute_pa…    ┆       ┆          ┆ te_paths.py      ┆   ┆          ┆       ┆        ┆        │\n",
      "└───────────────────┴───────┴──────────┴──────────────────┴───┴──────────┴───────┴────────┴────────┘\n",
      "Extension counts:\n",
      "filoma.DataFrame with 3 rows\n",
      "shape: (3, 2)\n",
      "┌────────────────┬─────┐\n",
      "│ extension      ┆ len │\n",
      "│ ---            ┆ --- │\n",
      "│ str            ┆ u32 │\n",
      "╞════════════════╪═════╡\n",
      "│ .pyc           ┆ 85  │\n",
      "│ .py            ┆ 37  │\n",
      "│ <no extension> ┆ 24  │\n",
      "└────────────────┴─────┘\n"
     ]
    }
   ],
   "source": [
    "from filoma import probe_to_df\n",
    "\n",
    "dir_path = \"../tests\"\n",
    "if dir_path is None:\n",
    "    print(\"No test directory available for probe_to_df; skip this cell.\")\n",
    "else:\n",
    "    try:\n",
    "        dfw = probe_to_df(dir_path, to_pandas=False, enrich=True, max_depth=2, threads=2)\n",
    "        print(\"probe_to_df returned a filoma.DataFrame with shape:\", dfw.shape)\n",
    "        # Show a small sample and a group_by_extension summary when available\n",
    "        try:\n",
    "            print(\"Sample rows:\")\n",
    "            print(dfw.head(5))\n",
    "        except Exception:\n",
    "            pass\n",
    "        try:\n",
    "            print(\"Extension counts:\")\n",
    "            print(dfw.group_by_extension().head(10))\n",
    "        except Exception as e:\n",
    "            print(\"group_by_extension failed:\", e)\n",
    "    except Exception as e:\n",
    "        print(\"probe_to_df failed:\", e)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4792a7e9",
   "metadata": {},
   "source": [
    "## 4) Image probing (in-memory)\n",
    "\n",
    "Create a small numpy array and pass it to `filoma.probe_image` to exercise the image path that accepts arrays. This avoids needing image files or heavy dependencies."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "01d15e2e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "probe_image on numpy array returned type: <class 'filoma.images.image_profiler.ImageReport'>\n",
      "ImageReport(path=None, file_type=None, shape=(16, 16), dtype='float64', min=-2.8289461122786097, max=2.6011147464964393, mean=0.034071740265040014, nans=0, infs=0, unique=256, status=None)\n"
     ]
    }
   ],
   "source": [
    "try:\n",
    "    import numpy as np\n",
    "\n",
    "    arr = np.random.randn(16, 16)\n",
    "    img_report = filoma.probe_image(arr)\n",
    "    print(\"probe_image on numpy array returned type:\", type(img_report))\n",
    "    try:\n",
    "        print(img_report)\n",
    "    except Exception:\n",
    "        pass\n",
    "except Exception as e:\n",
    "    print(\"Skipping image probe; numpy unavailable or probe failed:\", e)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d521ed6e",
   "metadata": {},
   "source": [
    "## 5) Save a small CSV export (if `polars` is available)\n",
    "\n",
    "This cell attempts to save the `probe_to_df` result or our small DataFrame example to `/tmp/filoma_example.csv`. It prints a short verification sample."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "77b6aacb",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Saved CSV to /tmp/filoma_example.csv\n",
      "CSV sample: ['path,depth,parent,name,stem,suffix,size_bytes,modified_time,created_time,is_file,is_dir,owner,group,mode_str,inode,nlink,sha256,xattrs', '../tests/test_async_rust_extra.py,1,../tests,test_async_rust_extra.py,test_async_rust_extra,.py,1938,2025-09-10 23:02:11,2025-09-10 23:02:11,true,false,kalfasy,kalfasy,-rw-rw-r--,7601345,1,,{}', '../tests/test_basic_dataframe.py,1,../tests,test_basic_dataframe.py,test_basic_dataframe,.py,1413,2025-09-10 23:02:12,2025-09-10 23:02:12,true,false,kalfasy,kalfasy,-rw-rw-r--,7602664,1,,{}', '../tests/scripts,1,../tests,scripts,scripts,\"\",4096,2025-09-04 20:14:19,2025-09-04 20:14:19,false,true,kalfasy,kalfasy,drwxrwxr-x,13593175,3,,{}', '../tests/test_ml_core.py,1,../tests,test_ml_core.py,test_ml_core,.py,5741,2025-09-20 21:41:56,2025-09-20 21:41:56,true,false,kalfasy,kalfasy,-rw-rw-r--,7602966,1,,{}', '../tests/test_rust_absolute_paths.py,1,../tests,test_rust_absolute_paths.py,test_rust_absolute_paths,.py,2589,2025-09-06 16:48:42,2025-09-06 16:48:42,true,false,kalfasy,kalfasy,-rw-rw-r--,7601819,1,,{}', '../tests/test_dataframe.py,1,../tests,test_dataframe.py,test_dataframe,.py,12731,2025-09-10 22:42:30,2025-09-10 22:42:30,true,false,kalfasy,kalfasy,-rw-rw-r--,7601601,1,,{}', '../tests/test_dataframe_chaining.py,1,../tests,test_dataframe_chaining.py,test_dataframe_chaining,.py,1142,2025-09-07 21:13:30,2025-09-07 21:13:30,true,false,kalfasy,kalfasy,-rw-rw-r--,7603121,1,,{}', '../tests/test_ml_path_col.py,1,../tests,test_ml_path_col.py,test_ml_path_col,.py,1010,2025-09-20 16:04:09,2025-09-20 16:04:09,true,false,kalfasy,kalfasy,-rw-rw-r--,7602942,1,,{}', '../tests/test_rust_comprehensive.py,1,../tests,test_rust_comprehensive.py,test_rust_comprehensive,.py,12431,2025-09-10 23:02:11,2025-09-10 23:02:11,true,false,kalfasy,kalfasy,-rw-rw-r--,7601605,1,,{}']\n"
     ]
    }
   ],
   "source": [
    "out_path = Path(\"/tmp/filoma_example.csv\")\n",
    "saved = False\n",
    "try:\n",
    "    if \"dfw\" in globals():\n",
    "        try:\n",
    "            dfw.df.write_csv(str(out_path))\n",
    "            saved = True\n",
    "        except Exception:\n",
    "            pass\n",
    "    if saved:\n",
    "        print(\"Saved CSV to\", out_path)\n",
    "        try:\n",
    "            print(\"CSV sample:\", out_path.read_text().splitlines()[:10])\n",
    "        except Exception:\n",
    "            pass\n",
    "    else:\n",
    "        print(\"Could not save CSV; polars or file-writer not available.\")\n",
    "except Exception as e:\n",
    "    print(\"Saving CSV failed:\", e)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "788e233a",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "### Notes and next steps\n",
    "\n",
    "- If a cell raised an exception because a dependency is missing, install `polars`, `numpy`, and optionally `pillow`.\n",
    "- To run longer scans increase `max_depth` and `threads` in the `probe()` calls.\n",
    "- Use `probe_to_df(..., to_pandas=True)` to get a pandas.DataFrame if you prefer pandas."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "filoma (3.11.11)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
