feat: one-click web multi-CSV analysis + CLI/desktop integrations#23
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ed41be031c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| path = Path(td) / name | ||
| path.write_text(text, encoding="utf-8") |
There was a problem hiding this comment.
Restrict upload paths to the temporary directory
/api/multi-analyze trusts the client-provided name and writes directly to Path(td) / name, so a crafted filename like ../../tmp/pwn.csv or an absolute path escapes the temp dir and allows overwriting arbitrary writable files on the host before analysis runs. This is a server-side file write primitive reachable by any caller of the endpoint; sanitize to a basename (or generate server-side names) and verify the resolved path stays under td before calling write_text.
Useful? React with 👍 / 👎.
| for i, f in enumerate(files): | ||
| if not isinstance(f, dict): | ||
| continue | ||
| name = str(f.get("name", f"file_{i}.csv")) |
There was a problem hiding this comment.
Ensure each uploaded CSV gets a unique temp filename
This code reuses the incoming name as the on-disk filename, so if two uploaded entries share a basename (for example two different data.csv files), the later write overwrites the earlier one and both analysis slots end up reading the same content. The request still succeeds, but the multi-file comparison is silently corrupted; append an index/UUID to each temp filename to preserve one file per upload item.
Useful? React with 👍 / 👎.
Motivation
--no-cachebehavior testable from the CLI.README.Description
POST /api/multi-analyzethat writes uploaded CSV texts to a temporary directory and callsanalyze_multiple_csv(..., use_cache=False)(file:bitnet_tools/web.py).group_column/target_columninputs, a run button that calls/api/multi-analyze, and automatic dashboard JSON population and rendering (files:bitnet_tools/ui/index.html,bitnet_tools/ui/app.js,bitnet_tools/ui/styles.css).bitnet_tools/multi_csv.py).bitnet_tools/visualize.py) and hooked optional chart generation into CLImulti-analyzewith error fallback.bitnet_tools/cli.py) withmulti-analyze,report,desktop, anddoctorsubcommands,--no-cacheflag passthrough, chart output support, and markdown report generation using new helpers (build_multi_csv_markdown,build_markdown_report).analysis.pystreaming summarizer to avoid loading all rows into memory and addedbuild_markdown_reportfor single-file reports.bitnet_tools/desktop.py,bitnet_desktop.pyw) and an environment diagnostic helper (bitnet_tools/doctor.py).README.mdto recalibrate the reported completion from ~98% to ~92%, documented the new web/desktop flows, and added a console script entrybitnet-desktopinpyproject.toml.tests/test_analysis.py,tests/test_cli.py).Testing
pytest -qand all tests passed:19 passed.Codex Task