Tags: SocketDev/socket-sdk-python
Tags
Add transient-error classification to APIFailure (#93) * Add transient-error classification to APIFailure API.do_request now records the HTTP status code on every exception it raises (status_code attribute), and APIFailure gains is_transient_error(): True for gateway/connection-level failures (HTTP 408/502/503/504, dropped or reset connections, client-side timeouts) where retrying the same request may succeed, False for deterministic errors (400/401/403/404/429, wrapped unexpected errors). Classification is based on the recorded status code rather than exception class identity or message text, so it stays correct if a status code gains a dedicated subclass later. Motivated by SocketDev/socket-python-cli#232: the CLI retries transient full-scan upload failures and previously had to parse the status code out of catch-all APIFailure message text. * Hardcode 502 in APIBadGateway instead of accepting a status_code The class definitionally represents a 502, so there is no reason for construction sites to pass (or be able to override) the status.
Add `sfw` aggregator gate to enforce required CI checks (#89) * ci: add Socket Firewall aggregator gate; bump 3.2.0 -> 3.2.1 Add a single sfw-gate job (if: always(), needs the conditional inspect + free/enterprise smoke + workflow-notice jobs) that fails only when an upstream job failed or was cancelled -- success and skipped both pass. This is the check intended to become the required status check on main: the smoke jobs are conditional (deps-changed gates them, and exactly one of free/enterprise runs per PR), so none can be required directly -- a required check whose job is if-skipped is never created and blocks merge forever. The gate is green when no deps change and is satisfied by whichever smoke path actually ran. NOT yet wired into branch protection -- added during a soak period so the check is visible before it becomes blocking, and so requiring it doesn't strand other open PRs. Pattern adapted from SocketDev/socket-python-cli #224. Signed-off-by: lelia <[email protected]> * ci: spell out 'iff' as 'if and only if' in gate comment Review feedback: 'iff' read as a typo. It is the logic shorthand for 'if and only if', but the comment exists to communicate, so spell it out. Signed-off-by: lelia <[email protected]> --------- Signed-off-by: lelia <[email protected]>
ci(deps): bump actions/github-script from 7.0.1 to 9.0.0 (#87) * ci(deps): bump actions/github-script from 7.0.1 to 9.0.0 Bumps [actions/github-script](https://github.com/actions/github-script) from 7.0.1 to 9.0.0. - [Release notes](https://github.com/actions/github-script/releases) - [Commits](actions/github-script@60a0d83...3a2844b) --- updated-dependencies: - dependency-name: actions/github-script dependency-version: 9.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <[email protected]> * Add version number as comment * Add version number as comment --------- Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: lelia <[email protected]>
Dependabot hardening + dependency update bundle (#84) * Harden Dependabot reviews and bundle dependency updates Mirrors the Dependabot hardening done in socket-python-cli (#207/#217/#218), adapted to this SDK (no Dockerfile, no e2e fixtures, hatch/pip build path). Bundle dependency updates (supersedes 4 open Dependabot PRs): - idna 3.11 -> 3.17 (security: CVE-2026-45409 quadratic-time DoS fix) - cryptography 46.0.5 -> 46.0.7 - pygments 2.19.2 -> 2.20.0 - uv 0.9.21 -> 0.11.17 Verified via uv sync --locked, import smoke, and pytest tests/unit (102 passed). Adds grouped/cooldowned dependabot.yml (uv + github-actions), a dependabot-review workflow running anonymous Socket Firewall smoke jobs, Version Check / PR Preview skips for Dependabot PRs, and setup-sfw / setup-hatch composite actions. Co-Authored-By: Claude Opus 4.8 <[email protected]> * chore(release): bump to 3.1.2 Version Check requires a package-version increment on maintainer PRs, and this PR bundles dependency bumps + Dependabot hardening. Bump version.py, pyproject.toml, and the uv.lock project version in sync. Co-Authored-By: Claude Opus 4.8 <[email protected]> * Extend dependency review to maintainers (free + enterprise SFW) Broaden dependabot-review into dependency-review so the Socket Firewall guardrail covers maintainer PRs too, not just Dependabot: - inspect now runs on every PR and computes the SFW edition per-PR: enterprise for a trusted SocketDev member (author_association OWNER/ MEMBER/COLLABORATOR) on an in-repo (non-fork) PR when SOCKET_API_TOKEN is present; free (anonymous) for Dependabot, forks, external contributors, or when the token is absent. - The mode degrades to free whenever the token is missing, so this is safe to ship before the secret exists and auto-upgrades to enterprise once SOCKET_API_TOKEN is added (repo or org level). The SDK has no Socket token today (cf. socket-python-cli's SOCKET_CLI_API_TOKEN). - setup-sfw composite action gains `mode` + `socket-token` inputs, forwarded to socketdev/action (same action, firewall-free vs firewall-enterprise). - Rename workflow dependabot-review.yml -> dependency-review.yml to match the broadened scope (not a required status check). Co-Authored-By: Claude Opus 4.8 <[email protected]> * fix(dependency-review): use runner Python, forbid uv interpreter download .python-version pins 3.12.7; setup-python provides 3.12.13, so `uv sync` tried to download the exact managed CPython from GitHub, which Socket Firewall's TLS interception blocked (UnknownIssuer). Set UV_PYTHON=3.12 + UV_PYTHON_DOWNLOADS=never so uv uses the runner interpreter and only PyPI package fetches route through sfw. Co-Authored-By: Claude Opus 4.8 <[email protected]> * fix(dependency-review): require strict org membership for enterprise SFW Tighten the enterprise-mode gate to author_association OWNER/MEMBER only. Outside collaborators (COLLABORATOR) now fall through to the free edition, same as Dependabot / forks / external contributors. Co-Authored-By: Claude Opus 4.8 <[email protected]> * chore(dependency-review): rename enterprise secret to SOCKET_SFW_API_TOKEN Co-Authored-By: Claude Opus 4.8 <[email protected]> * fix(dependency-review): scope SFW token to a dedicated environment Resolve zizmor secrets-outside-env (medium) without suppressing it. Split the single mode-switching smoke job into two: - python-sfw-smoke-free: untrusted PRs (Dependabot, forks, outside collaborators, externals). Anonymous free edition, never references the token. - python-sfw-smoke-enterprise: SocketDev org members (OWNER/MEMBER) on an in-repo PR. Authenticated enterprise edition; SOCKET_SFW_API_TOKEN is scoped to the `socket-firewall` GitHub environment, so only this job can read it. inspect now classifies PR trust (author_association OWNER/MEMBER, non-fork, non-Dependabot) and references no secret. No required-reviewer protection on the environment, so trusted dep PRs still run automatically. Co-Authored-By: Claude Opus 4.8 <[email protected]> * fix(dependency-review): gate enterprise on write-access (non-fork), not author_association author_association only reflects PUBLIC org membership, so private members (the common case here) show as CONTRIBUTOR and were misclassified -> the enterprise job always skipped. Switch the trust gate to "non-fork PR and not Dependabot": only accounts with write access can push an in-repo branch, the same boundary GitHub uses for secret exposure. No read:org token needed. Co-Authored-By: Claude Opus 4.8 <[email protected]> * ci(dependency-review): upload SFW smoke artifacts * ci(dependency-review): include SFW JSON report artifact * ci(dependency-review): read SFW report path from env var, drop stdout scrape Match socket-python-cli: discover the firewall report via the $SFW_JSON_REPORT_PATH env var that socketdev/action exports, instead of parsing the 'sfw report written to:' line out of stdout. The two sync steps return to plain 'set -o pipefail' + tee. A new 'Collect SFW JSON report' step (if: always(), before each upload) copies $SFW_JSON_REPORT_PATH into sfw-artifacts/sfw-report.json -- copy, not move, since socketdev/action's post step reads that temp path for its job summary -- and drops a sfw-report-missing.txt breadcrumb when absent. More robust than scraping an undocumented log string, and keeps the report-capture pattern uniform across both repos. Signed-off-by: lelia <[email protected]> --------- Signed-off-by: lelia <[email protected]> Co-authored-by: Claude Opus 4.8 <[email protected]>
Fix stale `didYouMean` props (#81) * test: failing regression for stale didYouMean props * fix(issues): drop stale didYouMean props, add detectedAt Resolves CUS2-5. The didYouMean class declared four props (alternatePackage, downloads, downloadsRatio, editDistance) but the current OpenAPI schema (socket-sdk-js/openapi.json:9298) only emits { alternatePackage, detectedAt }. The three stale keys were dead at runtime and detectedAt was missing a human-readable label entirely. Updated to match the schema. * chore(release): bump to 3.1.1 and sync pyproject.toml Run via .hooks/sync_version.py after merging origin/main (now at 3.1.0 from lelia's purl PR). Keeps pyproject.toml and socketdev/version.py in lockstep, as flagged in code review. * chore: sync uv.lock to 3.1.1
Support org-scoped batch package endpoint (#76) * Add org slug param with org-scoped routing, deprecation warning Signed-off-by: lelia <[email protected]> * Add org-scoped + legacy endpoint test coverage, bump lodash placeholders Signed-off-by: lelia <[email protected]> * Bump version for minor release rev Signed-off-by: lelia <[email protected]> * Fix github project homepage on PyPI Signed-off-by: lelia <[email protected]> * Fix RST formatting for title underlines Signed-off-by: lelia <[email protected]> --------- Signed-off-by: lelia <[email protected]> Co-authored-by: Eric Hibbs <[email protected]>
fix: tolerate unknown SocketCategory values in SocketAlert.from_dict (#… …79) * fix: tolerate unknown SocketCategory values in SocketAlert.from_dict The Socket API can emit category values the SDK does not yet know about (e.g. "other"). Strict enum construction in SocketAlert.from_dict turned that into a hard failure that propagated up through stream_diff and crashed any consumer that happened to receive such an alert. Fall back to SocketCategory.MISCELLANEOUS and log a warning when the value is unrecognized, so the SDK stays forward-compatible with new server-side categories without needing a coordinated release. Fixes #78. * chore: bump version to 3.0.33
PreviousNext