fix(deps): bump pillow and selenium minimum floors to patched versions - #5
Closed
dominicci13 wants to merge 36 commits into
Closed
fix(deps): bump pillow and selenium minimum floors to patched versions#5dominicci13 wants to merge 36 commits into
dominicci13 wants to merge 36 commits into
Conversation
- Added database_utils, excel_utils, schedule_utils, screenshot_utils, ui_utils, file_utils modules - Added upsert_dataframe(), get_verification_code(), run_on_schedule(), crop_to_element(), crop_to_box(), paste_to_excel(), load_config_safe() - Moved hardcoded account data to config/accounts.json (gitignored) - Moved SMTP sender and SellerCloud URLs to env vars via get_env() - Fixed kill_app() command injection, temp file paths, files_info() bug - Replaced quit() with raise RuntimeError in insert_dataframe() - Merged safe_start_browser() into start_browser() with retry_count param - Removed firefox.py, legacy schedule sleep helpers - Full type hints and Args/Returns/Raises docstrings across all modules - Added LICENSE (MIT), README.md, updated CHANGELOG.md and .gitignore - Removed egg-info from version control
…unts.json.example
Removed: - logging_utils module (setup_logger) — suite uses rich.print - alert_utils.send_error_email — handle_crash covers alerting via Outlook - config_utils.load_env — every consumer uses python-dotenv directly - custom_functions: download_finished, find_file, files_info, tomorrow, yesterday - database_utils.upsert_dataframe — added in 0.2.0 but never adopted - python-dotenv from pyproject.toml deps (no fc_utils module imports it) Added: - accounts.iter_amazon_accounts() generator yielding (key, name, url) - file_utils.latest_modified_date(path) returning the latest mtime as datetime, or None Improvements: - accounts: config/accounts.json resolved relative to sys.argv[0] entry script, falling back to CWD (robust against Task Scheduler launches) - custom_functions.shadow_element: fixed broken by_map[True] dispatch with explicit if/elif cascade - accounts.amazon_login: delegates OTP polling to get_verification_code; new retry_url parameter replaces unbounded retry loops at call sites (capped at 5 attempts) - outlook.get_verification_code: new consume=True flag marks the matched message as read and deletes it after extraction - schedule_utils.run_on_schedule: SIGINT handler shuts down the scheduler immediately on Windows (BlockingScheduler.Event.wait was blocking SIGINT until the next fire) Packaging: - Version bumped to 0.3.0 - __init__.py __all__ reduced to actually-used symbols
Single entry point that wires a Rich console handler (colorized output,
markup rendering, rich tracebacks) plus a 1 MB rotating file handler
writing plain-text logs to logs/<name>.log. Safe to call multiple times
in one process; handlers are only installed on the first call.
Consumers replace ad-hoc rich.print imports plus custom logging blocks
with a single line:
from fc_utils.logging_utils import setup_logging
log = setup_logging("my_automation")
Previous implementation queried sheet.range(f"{column}{row}").value once
per row inside a Python loop — one COM round-trip per cell. For a table
with N rows that was N+1 COM calls.
This rewrite reads the whole column in a single COM call and scans the
resulting list in pure Python, so the cost is always 2 COM calls
regardless of table size. The win scales linearly with row count.
Signature and return semantics are unchanged so existing callers
(eBay-Pending-Offers and other automations) keep working.
BlockingScheduler.start() on Windows blocks in a C-level threading.Event.wait() whose timeout is sized to the next job — which can be many hours away. Python signal delivery (SIGINT) is queued while that wait is in progress and only handled when the wait returns, so Ctrl+C is effectively swallowed until the next job runs. Switch to BackgroundScheduler plus a `while True: time.sleep(1)` loop in the main thread. time.sleep on Windows IS interruptible by Ctrl+C, so KeyboardInterrupt propagates immediately, the scheduler shuts down cleanly in `finally`, and the process exits. The scheduler's own daemon thread continues to block efficiently until the next fire time, so the heartbeat tick costs near-zero CPU. The previous custom SIGINT handler is removed — KeyboardInterrupt propagation handles shutdown directly.
- Register SUCCESS=25 custom log level + Logger.success() method bound at import. - Add RichLevelFormatter that prepends colored [LEVELNAME] tag per message (cyan/INFO, green/SUCCESS, yellow/WARNING, red/ERROR, bold red/CRITICAL, dim/DEBUG). - setup_logging() now wires RichHandler with show_level=False and the new formatter so the level appears exactly once, regardless of whether callers also embed [LEVEL] markup in their messages. File handler unchanged. - Bump version to 0.4.0.
Every fc_utils submodule now uses the standard logging API instead of rich.print: - Each module declares `log = logging.getLogger(__name__)` at module scope (or relies on it via the existing `setup_logging` consumer for log handler config). - All 47 print() call sites across 12 modules were converted to the matching log.info / log.success / log.warning / log.error. - The `from rich import print` shadowing import was removed everywhere. - Inline [cyan][INFO][/cyan] / [bold red][ERROR][/bold red] markup was stripped from each log call — the formatter from v0.4.0 supplies the colored level tag, so the previous inline markers were redundant. - Library code now writes silently when called from a context without a configured logger (tests, REPL) instead of unconditionally rendering Rich markup to stdout. Bumped version to 0.5.0.
…download_report New fc_utils.sellercloud module provides reusable SellerCloud automations: - request_custom_export(driver, custom_template, sku_list=None, product_group=None) drives the Manage Catalog grid through the Export Products wizard with a named Custom Export template. Filters the grid by URL (SKU CSV or product group id, never both). Returns the notify-download URL. Validation raises ValueError if neither/both of sku_list/product_group are supplied, if sku_list is empty, if more than 100 SKUs are passed, or if the template name is not in the wizard dropdown. - download_report(driver, download_url, download_path, output_path, ...) polls the notify-download URL, clicks the download button when SellerCloud finishes generating the report, waits for the .xlsx to land in the local downloads directory, and moves it to the caller-supplied output_path. Both functions read DOM selectors and URLs from config/selectors.json and config/paths.json (resolved relative to the entry script, like accounts.py). Consumers own those JSON files in their own repo and typically gitignore them. Both exported at the package root: from fc_utils import request_custom_export, download_report. Bumped version to 0.6.0.
sellercloud.download_report previously hardcoded `.xlsx` when constructing the expected filename in download_path. That broke CSV and TSV exports because the file Chrome dropped never matched the polled name. Now the function reads `output_path.suffix` and uses that for the download filename, so .csv, .xlsx, and .tsv outputs all work with no caller changes. Falls back to .xlsx only if output_path has no suffix.
- chrome.py: move 'import logging' up to the stdlib import block (was sandwiched between the third-party imports and the first-party fc_utils.custom_functions import). - .gitignore: ignore ruvector.db (Ruflo plugin artifact).
Centralizes browser-debug screenshot capture under screenshots/<root>/ <section>/<description>_<timestamp>.png with filesystem-safe sanitization. Lets consumer repos drop ad-hoc desktop-rooted save_screenshot() calls.
win32com.Dispatch needs CoInitialize on the calling thread. Under APScheduler the job runs on a worker thread that never had COM set up; xlwings-based jobs only worked because opening Excel initialized COM as a side effect. openpyxl-only jobs (and any crash-alert before the first Excel write) hit com_error -2147221008 at send_email and lost the alert path. send_email/get_account now call a thread-local-guarded _ensure_com() before any Dispatch.
…rsions pillow>=10.0.0 allows installs with 12 known CVEs; bump floor to 12.3.0. selenium>=4.0.0 allows PYSEC-2023-206; bump floor to 4.14.0.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Monthly dependency security sweep (2026-07). Two direct dependencies in
pyproject.tomlhave minimum-version floors that permit installation of versions with known CVEs.Vulnerable pins → fixed pins
pillow>=10.0.0>=12.3.0selenium>=4.0.0>=4.14.0Notes
pywin32could not be audited (Windows-only; no Linux distribution available forpip-audit).seleniumbase>=4.0.0pulls in stale transitive dependencies (cryptography,urllib3,requests,idna,h11,pymysql,pyopenssl,ipython,pygments,soupsieve,pytest) with many known CVEs when resolved at its minimum version 4.0.0. These are not direct deps in this file and are not changed here; a follow-up to raise theseleniumbasefloor or pin transitive deps is recommended.shared-python-utilswas accessible in this session. The other fleet repos (amzn-*,ebay-*,bb-*,all-dashboards-report,sellercloud-sync) were denied by the session's GitHub scope — see the tracking issue for next steps.Audit tool:
pip-audit 2.10.1against PyPI/OSVDo not merge to main without verifying compatibility with the Windows runtime environment.
Generated by Claude Code