-
Notifications
You must be signed in to change notification settings - Fork 11
Permalink
Choose a base ref
{{ refName }}
default
Choose a head ref
{{ refName }}
default
Comparing changes
Choose two branches to see what’s changed or to start a new pull request.
If you need to, you can also or
learn more about diff comparisons.
Open a pull request
Create a new pull request by comparing changes across two branches. If you need to, you can also .
Learn more about diff comparisons here.
base repository: SocketDev/socket-python-cli
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v2.4.8
Could not load branches
Nothing to show
Loading
Could not load tags
Nothing to show
{{ refName }}
default
Loading
...
head repository: SocketDev/socket-python-cli
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v2.4.9
Could not load branches
Nothing to show
Loading
Could not load tags
Nothing to show
{{ refName }}
default
Loading
- 1 commit
- 12 files changed
- 1 contributor
Commits on Jun 12, 2026
-
feat: stream CLI log transcripts and run status to Socket backend (#201)
* feat: stream CLI logs to /python-cli-runs/* lifecycle endpoints Buffer the CLI's own log records and POST them in 5s batches to a new register/upload/finalize lifecycle so the admin dashboard renders what the user saw in their terminal alongside the run's terminal status. New modules: - core/cli_run.py — register_cli_run / finalize_cli_run helpers - core/log_uploader.py — BatchedLogUploader (daemon-thread flusher, chunked under the 256KB cap, swallows network errors, drains on shutdown) and UploadingLogHandler routing log records to it - core/streaming.py — setup_streaming() wires both into the socketcli and socketdev loggers, forces them to DEBUG so uploads capture the full history regardless of local terminal verbosity, and returns a teardown callable for the caller to register with atexit - set_run_status() propagates the terminal status through the teardown; socketcli.py exception handlers call it for KeyboardInterrupt (cancelled), uncaught Exception (failure), and any SystemExit with a non-zero code (failure) so sys.exit() paths inside main_code surface correctly instead of defaulting to success Best-effort end-to-end: registration failures fall back to no-streaming and never block the scan. Opt out with --disable-server-log-streaming. Tested against local depscan with the matching /v0/python-cli-runs/* endpoints; 173 unit tests pass. * chore: drop per-batch size chunking to match upstream uploader The 256 KB ceiling I added speculatively when the server cap was 256 KB no longer matches the reference implementation we're mirroring, which sends each flush as a single POST regardless of size. With the server cap now well above any plausible single-flush volume, chunking is unnecessary and divergent — drop it. Removes _chunk_by_size, _MAX_BATCH_BYTES, and the four chunking tests. _flush now POSTs the entire buffered batch as one request. * chore: drop integration field from cli-run register payload The server-side handler now rejects unknown fields and the integration column has been removed from the schema (it was plumbed end-to-end but never displayed, filtered, or grouped on). Stop sending it. Removes the integration parameter from register_cli_run and setup_streaming, drops the corresponding wiring in socketcli.py, and prunes the now-pointless test_register_cli_run_omits_integration_when_falsy case. * feat: link cli-run to its full_scan via report_run_id on finalize The depscan side now joins cli_run → full_scans → repositories via the report_run_id field to surface the scanned repo in the admin dashboard view of each CLI run. Wire the CLI to send the full_scan_id (== the report_run_id depscan expects) when it has one. - finalize_cli_run accepts an optional report_run_id and includes it (nullable) in the POST body. - streaming.py adds a module-level _report_run_id holder and a set_report_run_id() setter; teardown passes it through to finalize. - socketcli.py captures diff.id at a single chokepoint after the diff-producing branches converge, guarded against the NO_DIFF_RAN / NO_SCAN_RAN sentinel values. The field is nullable end-to-end so CLI invocations that fail before producing a diff (or are run in modes that don't create one) still finalize cleanly. * chore: bump version to 2.2.87 for streaming logs feature - socketsecurity/__init__.py: __version__ → 2.2.87 - pyproject.toml: version → 2.2.87 - CHANGELOG.md: new 2.2.87 entry describing the streaming-logs feature Required by .github/workflows/version-check.yml, which fails the PR if the version isn't incremented relative to main. * feat: flip streaming logs to opt-in via --upload-logs The Socket backend changed its register contract so that log streaming is now opt-in rather than default-on. The CLI always calls register (cheap, lets the server force-enable for specific orgs) and gates the downstream upload/finalize lifecycle on the response. Wire changes: - POST /v0/python-cli-runs body adds a required `share_logs` field. - Response: { log_streaming_enabled: bool, run_id: <uuid|null> }. When log_streaming_enabled is false, run_id is null and the CLI skips the upload + finalize calls entirely. CLI changes: - New `--upload-logs` flag (default off). When set, the CLI sends share_logs=true on register. - Removed `--disable-server-log-streaming` — default is off, so an opt-out flag no longer makes sense. - register_cli_run takes a required share_logs arg and returns None whenever log_streaming_enabled is false (whatever the reason: client opted out, server denied, server unreachable). Bumps version to 2.2.88 and updates the CHANGELOG entry to reflect the opt-in shape. * chore: regenerate uv.lock for version 2.4.8 The version-check workflow added in main now requires uv.lock to be updated whenever pyproject.toml changes, and the SFW smoke jobs run `uv sync --locked`, which fails on an out-of-sync lockfile. * feat: add --no-upload-logs to explicitly decline log upload Backend now distinguishes "user wants out" from "user said nothing": - `decline_logs: true` (the new flag) overrides every other signal including the server-side org-level override, so users with a legal/consent reason for no upload get a guaranteed off. - `share_logs: true` (the existing --upload-logs) opts in. - Otherwise the server applies its own policy. Argparse enforces that --upload-logs and --no-upload-logs are mutually exclusive (post-parse check via parser.error so dash/underscore aliases on either side still coexist with the same dests). register_cli_run now sends both `share_logs` and `decline_logs` in the payload; setup_streaming forwards both. CHANGELOG 2.4.8 entry updated to call out --no-upload-logs alongside --upload-logs. * chore: bump version to 2.4.9 2.4.8 already shipped with the full-scan retry fix; this release adds the opt-in --upload-logs streaming channel. * chore: bump __version__ to 2.4.9 version-check reads socketsecurity/__init__.py; the previous bump only touched pyproject.toml. * refactor: address PR review on streaming logs - collapse upload_logs/decline_logs config fields into a single Optional[bool] (tri-state); projection to share_logs/decline_logs happens at the setup_streaming call site. - streaming.py: replace module-level globals + atexit teardown with a StreamingLogs context manager. set_run_status disappears entirely — __exit__ infers the run status from the exception that closed the with block. set_report_run_id is now an instance method. Logger handler wiring iterates over (cli_logger, sdk_logger) instead of repeating itself. - log_uploader.py: drop _LEVEL_MAP, use logging.getLevelName directly. Wire format changes WARN/ERROR-for-CRITICAL to WARNING/CRITICAL. - log_uploader.py: tidy BatchedLogUploader.stop so the final _flush always runs and the thread shutdown only runs when there is a thread. - socketcli.py: wrap main_code body in 'with setup_streaming(...) as streaming:'; cli()'s exception handlers no longer need to set status before re-raising. - tests updated for the CM API and the new level strings. * test(log_uploader): cover cross-thread emit during active flush Adds a deterministic regression test that parks the uploader thread inside _flush() via a threading.Event, emits a real log record from the main thread while _FLUSH_GUARD.active is set on the uploader thread, and asserts the record lands in the next batch (not dropped). Documents that the thread-local guard only blocks recursive emits on the uploader thread itself. * refactor(config): use store_const + mutually exclusive group for log-upload flags --upload-logs and --no-upload-logs now share dest='upload_logs' via store_const (True/False) in an argparse mutually exclusive group. argparse handles the conflict natively; drop the manual mutex check and the tri-state mapping in from_args. args.upload_logs is now Optional[bool] directly. The undocumented --upload_logs / --no_upload_logs snake_case aliases are dropped (introduced earlier in this same unreleased branch; no users to break). * refactor: push upload_logs tri-state down to the API boundary - register_cli_run now takes upload_logs: Optional[bool] directly and projects to share_logs/decline_logs only when building the JSON payload. The invalid (share=True, decline=True) state is now unrepresentable above the wire boundary. - StreamingLogs.__init__ takes upload_logs instead of the two booleans; the call site in socketcli.py just passes config.upload_logs through. - Drop the setup_streaming alias; call sites use StreamingLogs directly. - Drop the dead 'except SystemExit: raise' in cli() — re-raising is the default for an unhandled exception path. - Tests updated for the new signatures. * fix(cli_run): broaden register exception handling to honor 'never break the scan' The earlier register_cli_run only caught APIFailure on the request and ValueError/JSONDecodeError on resp.json(). If the server returned JSON that parsed but wasn't an object (e.g. a list), body.get(...) would raise AttributeError and propagate out of StreamingLogs.__enter__, crashing the CLI before the scan even starts. Collapse the request + parse + field-extraction into a single try with a broad except so any unexpected failure — known or otherwise — falls back to no-streaming, matching the module docstring's promise. Add regression tests for non-dict JSON bodies and arbitrary unexpected exceptions from client.request.Configuration menu - View commit details
-
Copy full SHA for 82a4756 - Browse repository at this point
Copy the full SHA 82a4756View commit details
Loading
This comparison is taking too long to generate.
Unfortunately it looks like we can’t render this comparison for you right now. It might be too big, or there might be something weird with your repository.
You can try running this command locally to see the comparison on your machine:
git diff v2.4.8...v2.4.9