Batch-download every client report in a single run — encrypted credentials, 52 tests.
A Windows desktop app that automates bulk PDF report downloads from web-based reporting portals. Configure once, click Start, and every client report lands in the output folder — no manual browser work required.
📸 Screenshot coming soon.
Downloading reports for dozens of clients means logging in, selecting each client, choosing a date range, clicking Run, waiting for the report to render, then downloading — repeated for every client, every month. With multiple report types (e.g. Total Effort and Momentum), that number doubles. This process is slow, error-prone, and kills productivity.
Report Downloader drives a headless Chromium browser via Playwright to perform the full login-to-download sequence automatically. Enter your client list once, pick the report type and month, click Start — the app iterates through every client, applies the correct date filters, downloads each report to a descriptive filename, and prints live progress as it goes.
- Batch Processing — Download reports for any number of clients in a single run
- Multiple Report Types — Select one or both report types (Total Effort, Momentum) per run
- DPAPI Credential Encryption — Credentials are stored encrypted via Windows DPAPI (
win32crypt); never saved in plaintext or source - Credential Redaction — Password is stripped from all log messages and exception traces before they reach the UI
- Date Range Picker — GUI calendar (tkcalendar) for selecting the report month/year
- Background Processing — Downloads run in a worker thread; the Tkinter UI stays responsive with a stop button
- Real-time Progress — Live log panel and per-client/per-report progress indicators
- Smart Collision Handling — Existing filenames get a
(2),(3)suffix rather than being overwritten - Graceful Session Cleanup — Attempts a clean Disconnect/Logout click after each run; warns if it cannot find the button
- Standalone Executable — PyInstaller build bundles Chromium into a single
.exe— no Python or browser installation needed on end-user machines - 52 Unit Tests — pytest suite covering config, naming, events, validators, worker orchestration, and automation helpers
Python 3.10+ · Playwright 1.49 · Tkinter · tkcalendar · pywin32 / DPAPI · PyInstaller · pytest · pytest-mock
git clone https://github.com/YOUR_USERNAME_HERE/report-downloader.git
cd report-downloader
pip install -r requirements.txt
playwright install chromium
python -m report_downloader.mainBuild a standalone .exe:
pip install pyinstaller
pyinstaller build.spec
# Output: dist/ — includes bundled Chromium, no separate install neededRun the test suite:
pytestOn first launch, open Settings and enter your reporting portal URL, credentials (saved DPAPI-encrypted in %LOCALAPPDATA%\ReportDownloader\config.json), and output folder. At runtime, a background worker thread launches headless Chromium, navigates to the URL, detects the login screen, submits credentials, then loops over each selected report type and each client: it sets the client filter, applies the date range, presses Execute, waits for the file to download into a temporary directory, then moves it to the output folder with a descriptive name (e.g. Acme April 2026 Total Effort.pdf). A threading.Event stop flag lets the UI cancel mid-run cleanly.
report-downloader/
├── requirements.txt
├── build.spec # PyInstaller build config
├── report_downloader/
│ ├── main.py # Entry point
│ ├── gui.py # Tkinter main window + settings panel
│ ├── worker.py # Background job orchestration
│ ├── config.py # Settings persistence (DPAPI encryption)
│ ├── events.py # Event dataclasses for thread → UI communication
│ ├── naming.py # Output filename builder + collision resolver
│ ├── reports.py # Report type definitions (Total Effort, Momentum)
│ ├── validators.py # GUI input validation
│ └── automation/
│ ├── browser.py # Playwright launch, login, disconnect
│ ├── report.py # Report page navigation
│ ├── filters.py # Client + date filter interactions
│ └── download.py # Execute + PDF/Excel capture
└── tests/ # pytest suite — 52 unit tests
├── test_config.py
├── test_download.py
├── test_events.py
├── test_filters.py
├── test_naming.py
├── test_reports.py
├── test_validators.py
└── test_worker.py
MIT © Abdul Raqeeb Khatri