From 3410fc927a3bf83193aa97e865857affdbc2377d Mon Sep 17 00:00:00 2001 From: Pepe Fagoaga Date: Thu, 14 May 2026 14:35:09 +0200 Subject: [PATCH] chore(security): replace safety with osv-scanner (#11167) --- .github/actions/osv-scanner/action.yml | 169 ++++++++++++++++++++ .github/scripts/osv-scan.sh | 122 +++++++++++++++ .github/workflows/api-security.yml | 27 ++-- .github/workflows/sdk-security.yml | 23 ++- .github/workflows/ui-security.yml | 75 +++++++++ .pre-commit-config.yaml | 10 -- .safety-policy.yml | 58 ------- action.yml | 2 +- api/pyproject.toml | 3 - api/uv.lock | 145 ----------------- pyproject.toml | 1 - scripts/setup-git-hooks.sh | 4 +- uv.lock | 207 ------------------------- 13 files changed, 403 insertions(+), 443 deletions(-) create mode 100644 .github/actions/osv-scanner/action.yml create mode 100755 .github/scripts/osv-scan.sh create mode 100644 .github/workflows/ui-security.yml delete mode 100644 .safety-policy.yml diff --git a/.github/actions/osv-scanner/action.yml b/.github/actions/osv-scanner/action.yml new file mode 100644 index 0000000000..4bfb5993cb --- /dev/null +++ b/.github/actions/osv-scanner/action.yml @@ -0,0 +1,169 @@ +name: 'OSV-Scanner' +description: 'Install osv-scanner and scan a lockfile, failing on HIGH/CRITICAL/UNKNOWN severity findings. Posts/updates a PR comment with findings on pull_request events (requires pull-requests: write).' +author: 'Prowler' + +inputs: + lockfile: + description: 'Path to the lockfile to scan, relative to the repository root (e.g. uv.lock, api/uv.lock, ui/pnpm-lock.yaml).' + required: true + severity-levels: + description: 'Comma-separated severity levels that fail the scan. Default: HIGH,CRITICAL,UNKNOWN.' + required: false + default: 'HIGH,CRITICAL,UNKNOWN' + version: + description: 'osv-scanner release tag to install. When overriding, you MUST also override binary-sha256.' + required: false + default: 'v2.3.8' + binary-sha256: + description: 'Expected SHA256 of osv-scanner_linux_amd64 for the given version. Default tracks v2.3.8. See https://github.com/google/osv-scanner/releases/download//osv-scanner_SHA256SUMS.' + required: false + default: 'bc98e15319ed0d515e3f9235287ba53cdc5535d576d24fd573978ecfe9ab92dc' + post-pr-comment: + description: 'Post or update a PR comment with the scan report. Only effective on pull_request events. Requires pull-requests: write permission on the caller job.' + required: false + default: 'true' + +runs: + using: 'composite' + steps: + - name: Install osv-scanner + shell: bash + env: + OSV_SCANNER_VERSION: ${{ inputs.version }} + # Download the binary AND the published SHA256SUMS file, then verify the + # binary checksum against the upstream-signed manifest. Aborts on mismatch. + run: | + set -euo pipefail + if command -v osv-scanner >/dev/null 2>&1; then + INSTALLED="$(osv-scanner --version 2>&1 | awk '/scanner version/ {print $NF; exit}')" + if [ "v${INSTALLED}" = "${OSV_SCANNER_VERSION}" ]; then + echo "osv-scanner ${OSV_SCANNER_VERSION} already installed." + exit 0 + fi + fi + BASE="https://github.com/google/osv-scanner/releases/download/${OSV_SCANNER_VERSION}" + BIN_NAME="osv-scanner_linux_amd64" + curl -fSL --retry 3 "${BASE}/${BIN_NAME}" -o "${RUNNER_TEMP}/${BIN_NAME}" + curl -fSL --retry 3 "${BASE}/osv-scanner_SHA256SUMS" -o "${RUNNER_TEMP}/osv-scanner_SHA256SUMS" + (cd "${RUNNER_TEMP}" && sha256sum --check --ignore-missing osv-scanner_SHA256SUMS) + chmod +x "${RUNNER_TEMP}/${BIN_NAME}" + sudo mv "${RUNNER_TEMP}/${BIN_NAME}" /usr/local/bin/osv-scanner + rm -f "${RUNNER_TEMP}/osv-scanner_SHA256SUMS" + osv-scanner --version + + - name: Run osv-scanner + id: scan + shell: bash + working-directory: ${{ github.workspace }} + env: + OSV_LOCKFILE: ${{ inputs.lockfile }} + OSV_SEVERITY_LEVELS: ${{ inputs.severity-levels }} + OSV_REPORT_FILE: ${{ runner.temp }}/osv-scanner-findings.json + # Per-vulnerability ignores (reason + expiry) live in osv-scanner.toml at the repo root, if present. + # Severity filter is enforced in the wrapper via OSV_SEVERITY_LEVELS. + # `continue-on-error: true` lets the PR-comment step run even when findings exist; + # the gate step below re-fails the job from the wrapper exit code. + continue-on-error: true + run: ./.github/scripts/osv-scan.sh --lockfile="${OSV_LOCKFILE}" + + - name: Post osv-scanner report on PR + if: >- + always() + && inputs.post-pr-comment == 'true' + && github.event_name == 'pull_request' + && github.event.pull_request.head.repo.full_name == github.repository + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + env: + OSV_REPORT_FILE: ${{ runner.temp }}/osv-scanner-findings.json + OSV_LOCKFILE: ${{ inputs.lockfile }} + OSV_SEVERITY_LEVELS: ${{ inputs.severity-levels }} + with: + script: | + const fs = require('fs'); + const lockfile = process.env.OSV_LOCKFILE; + const severityLevels = process.env.OSV_SEVERITY_LEVELS; + const reportFile = process.env.OSV_REPORT_FILE; + const marker = ``; + const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`; + + let findings = []; + if (fs.existsSync(reportFile)) { + try { + findings = JSON.parse(fs.readFileSync(reportFile, 'utf8')); + } catch (err) { + core.warning(`Could not parse ${reportFile}: ${err.message}`); + return; + } + } + + const { data: comments } = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + }); + const existing = comments.find(c => c.body?.includes(marker)); + + if (findings.length === 0) { + if (existing) { + await github.rest.issues.deleteComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: existing.id, + }); + core.info(`Deleted stale osv-scanner comment for ${lockfile}.`); + } else { + core.info(`No findings and no stale comment for ${lockfile}.`); + } + return; + } + + const sevIcon = (s) => ({ + CRITICAL: '🔴', HIGH: '🟠', MEDIUM: '🟡', LOW: '🟢', UNKNOWN: '⚪', + }[s] || '⚪'); + const escape = (s) => String(s ?? '').replace(/\|/g, '\\|').replace(/\n/g, ' '); + const rows = findings.map(f => + `| ${sevIcon(f.severity)} ${f.severity}${f.score ? ` (${f.score})` : ''} | \`${escape(f.id)}\` | \`${escape(f.ecosystem)}/${escape(f.package)}\` | \`${escape(f.version)}\` | ${escape(f.summary || '(no summary)')} |` + ); + + const body = [ + marker, + `## 🔒 osv-scanner: ${findings.length} finding(s) in \`${lockfile}\``, + '', + `Severity gate: \`${severityLevels}\``, + '', + '| Severity | ID | Package | Version | Summary |', + '|----------|----|---------|---------|---------|', + ...rows, + '', + `To accept a finding, add an \`[[IgnoredVulns]]\` entry to \`osv-scanner.toml\` at the repo root with a reason and \`ignoreUntil\`.`, + '', + `[View run](${runUrl})`, + ].join('\n'); + + if (existing) { + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: existing.id, + body, + }); + core.info(`Updated osv-scanner comment for ${lockfile}.`); + } else { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body, + }); + core.info(`Posted new osv-scanner comment for ${lockfile}.`); + } + + - name: Enforce osv-scanner severity gate + shell: bash + env: + SCAN_OUTCOME: ${{ steps.scan.outcome }} + run: | + if [ "${SCAN_OUTCOME}" != "success" ]; then + echo "osv-scanner gate: scan reported findings (outcome=${SCAN_OUTCOME})" >&2 + exit 1 + fi diff --git a/.github/scripts/osv-scan.sh b/.github/scripts/osv-scan.sh new file mode 100755 index 0000000000..d9c2e1a901 --- /dev/null +++ b/.github/scripts/osv-scan.sh @@ -0,0 +1,122 @@ +#!/usr/bin/env bash +# Run osv-scanner and fail when findings match the configured severity levels. +# +# Replaces `safety check --policy-file .safety-policy.yml`. Used by: +# - .github/actions/osv-scanner/action.yml (composite action) +# - .github/workflows/api-security.yml, sdk-security.yml, ui-security.yml +# +# Severity levels (comma-separated) are read from OSV_SEVERITY_LEVELS. +# Default: HIGH,CRITICAL,UNKNOWN — preserves prior .safety-policy.yml policy +# (ignore-cvss-severity-below: 7 + ignore-cvss-unknown-severity: False). +# osv-scanner has no native CVSS threshold (google/osv-scanner#1400, closed +# not-planned). Severity is derived from $group.max_severity (numeric CVSS +# score string) which osv-scanner emits per group. +# +# CVSS v3 score → categorical label: +# CRITICAL >= 9.0 +# HIGH >= 7.0 +# MEDIUM >= 4.0 +# LOW > 0.0 +# UNKNOWN no score available +# +# Per-vulnerability ignores (with reason + expiry) live in osv-scanner.toml at +# the repo root, if it exists. Without that file, osv-scanner uses defaults. +# +# Usage: +# osv-scan.sh [osv-scanner pass-through args...] +# Examples: +# osv-scan.sh --lockfile=uv.lock +# osv-scan.sh --recursive . +# OSV_SEVERITY_LEVELS=CRITICAL osv-scan.sh --lockfile=uv.lock + +set -euo pipefail + +ROOT="$(git rev-parse --show-toplevel)" +CONFIG="${ROOT}/osv-scanner.toml" +SEVERITY_LEVELS="${OSV_SEVERITY_LEVELS:-HIGH,CRITICAL,UNKNOWN}" + +for bin in osv-scanner jq; do + if ! command -v "${bin}" >/dev/null 2>&1; then + echo "error: ${bin} not found in PATH" >&2 + exit 2 + fi +done + +SCAN_ARGS=() +if [ -f "${CONFIG}" ]; then + SCAN_ARGS+=(--config="${CONFIG}") +fi + +# Exit codes: 0=clean, 1=findings, 127=no supported files, 128=internal error. +STDERR="$(mktemp)" +trap 'rm -f "${STDERR}"' EXIT + +set +e +OUTPUT="$(osv-scanner scan source "${SCAN_ARGS[@]}" --format=json "$@" 2>"${STDERR}")" +RC=$? +set -e + +case "${RC}" in + 0|1) ;; + 127) echo "osv-scanner: no supported lockfiles in scan target"; exit 0 ;; + *) + echo "osv-scanner: exited with code ${RC}" >&2 + [ -s "${STDERR}" ] && cat "${STDERR}" >&2 + exit "${RC}" + ;; +esac + +# Build a JSON array of normalized severity levels for jq. +SEVERITY_JSON="$(printf '%s' "${SEVERITY_LEVELS}" | jq -Rc ' + split(",") | map(ascii_upcase | sub("^\\s+"; "") | sub("\\s+$"; "")) +')" + +# Walk each vulnerability, look up its group's max_severity (numeric CVSS), +# map to a categorical label, then filter by OSV_SEVERITY_LEVELS. +FINDINGS="$(printf '%s' "${OUTPUT}" | jq --argjson sevs "${SEVERITY_JSON}" ' + [ .results[]?.packages[]? + | . as $pkg + | ($pkg.groups // []) as $groups + | ($pkg.vulnerabilities // [])[] + | . as $vuln + | ([ $groups[] | select((.ids // []) | index($vuln.id)) ][0] // {}) as $group + | (($group.max_severity // "") | tonumber? // null) as $score + | (if $score == null then "UNKNOWN" + elif $score >= 9.0 then "CRITICAL" + elif $score >= 7.0 then "HIGH" + elif $score >= 4.0 then "MEDIUM" + elif $score > 0 then "LOW" + else "UNKNOWN" + end) as $label + | { + id: $vuln.id, + severity: $label, + score: $score, + summary: ($vuln.summary // null), + package: $pkg.package.name, + version: $pkg.package.version, + ecosystem: $pkg.package.ecosystem + } + | select(.severity as $s | $sevs | any(. == $s)) + ] +')" + +COUNT="$(printf '%s' "${FINDINGS}" | jq 'length')" + +# Write the findings JSON to OSV_REPORT_FILE so callers (e.g. the composite +# action's PR-comment step) can consume the same data the gate decision uses. +if [ -n "${OSV_REPORT_FILE:-}" ]; then + printf '%s' "${FINDINGS}" > "${OSV_REPORT_FILE}" +fi + +if [ "${COUNT}" -gt 0 ]; then + echo "osv-scanner: ${COUNT} finding(s) at severity ${SEVERITY_LEVELS}" + printf '%s' "${FINDINGS}" | jq -r ' + .[] | " [\(.severity)\(if .score then " \(.score)" else "" end)] \(.id) \(.ecosystem)/\(.package)@\(.version) — \(.summary // "(no summary)")" + ' + echo + echo "To accept a finding, create osv-scanner.toml at the repo root with a reason and ignoreUntil." + exit 1 +fi + +echo "osv-scanner: no findings at severity levels: ${SEVERITY_LEVELS}" diff --git a/.github/workflows/api-security.yml b/.github/workflows/api-security.yml index 1b2d01e34e..abcaad13dc 100644 --- a/.github/workflows/api-security.yml +++ b/.github/workflows/api-security.yml @@ -10,6 +10,8 @@ on: - '.github/workflows/api-tests.yml' - '.github/workflows/api-security.yml' - '.github/actions/setup-python-uv/**' + - '.github/actions/osv-scanner/**' + - '.github/scripts/osv-scan.sh' pull_request: branches: - "master" @@ -19,6 +21,8 @@ on: - '.github/workflows/api-tests.yml' - '.github/workflows/api-security.yml' - '.github/actions/setup-python-uv/**' + - '.github/actions/osv-scanner/**' + - '.github/scripts/osv-scan.sh' concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -35,6 +39,7 @@ jobs: timeout-minutes: 15 permissions: contents: read + pull-requests: write # osv-scanner action posts/updates a PR comment with findings strategy: matrix: python-version: @@ -52,11 +57,12 @@ jobs: pypi.org:443 files.pythonhosted.org:443 github.com:443 - auth.safetycli.com:443 - pyup.io:443 - raw.githubusercontent.com:443 - data.safetycli.com:443 api.github.com:443 + objects.githubusercontent.com:443 + release-assets.githubusercontent.com:443 + api.osv.dev:443 + api.deps.dev:443 + osv-vulnerabilities.storage.googleapis.com:443 - name: Checkout repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -71,7 +77,8 @@ jobs: files: | api/** .github/workflows/api-security.yml - .safety-policy.yml + .github/actions/osv-scanner/** + .github/scripts/osv-scan.sh files_ignore: | api/docs/** api/README.md @@ -91,11 +98,13 @@ jobs: # bandit would recurse into installed third-party packages. run: uv run bandit -q -lll -x '*_test.py,./contrib/,./.venv/' -r . - - name: Safety + - name: Dependency vulnerability scan with osv-scanner if: steps.check-changes.outputs.any_changed == 'true' - # Accepted CVEs, severity threshold, and ignore expirations live in ../.safety-policy.yml - run: uv run safety check --policy-file ../.safety-policy.yml + uses: ./.github/actions/osv-scanner + with: + lockfile: api/uv.lock - name: Vulture - if: steps.check-changes.outputs.any_changed == 'true' + # Run even when osv-scanner reports findings so dead-code signal isn't masked by SCA failures. + if: ${{ !cancelled() && steps.check-changes.outputs.any_changed == 'true' }} run: uv run vulture --exclude "contrib,tests,conftest.py,.venv" --min-confidence 100 . diff --git a/.github/workflows/sdk-security.yml b/.github/workflows/sdk-security.yml index 39ff918097..fe7bb4217e 100644 --- a/.github/workflows/sdk-security.yml +++ b/.github/workflows/sdk-security.yml @@ -13,6 +13,8 @@ on: - '.github/workflows/sdk-tests.yml' - '.github/workflows/sdk-security.yml' - '.github/actions/setup-python-uv/**' + - '.github/actions/osv-scanner/**' + - '.github/scripts/osv-scan.sh' pull_request: branches: - 'master' @@ -25,6 +27,8 @@ on: - '.github/workflows/sdk-tests.yml' - '.github/workflows/sdk-security.yml' - '.github/actions/setup-python-uv/**' + - '.github/actions/osv-scanner/**' + - '.github/scripts/osv-scan.sh' concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -39,6 +43,7 @@ jobs: timeout-minutes: 15 permissions: contents: read + pull-requests: write # osv-scanner action posts/updates a PR comment with findings steps: - name: Harden Runner @@ -49,10 +54,12 @@ jobs: pypi.org:443 files.pythonhosted.org:443 github.com:443 - auth.safetycli.com:443 - pyup.io:443 - data.safetycli.com:443 api.github.com:443 + objects.githubusercontent.com:443 + release-assets.githubusercontent.com:443 + api.osv.dev:443 + api.deps.dev:443 + osv-vulnerabilities.storage.googleapis.com:443 - name: Checkout repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -97,11 +104,13 @@ jobs: if: steps.check-changes.outputs.any_changed == 'true' run: uv run bandit -q -lll -x '*_test.py,./.venv/,./contrib/,./api/,./ui' -r . - - name: Security scan with Safety + - name: Dependency vulnerability scan with osv-scanner if: steps.check-changes.outputs.any_changed == 'true' - # Accepted CVEs, severity threshold, and ignore expirations live in .safety-policy.yml - run: uv run safety check -r pyproject.toml --policy-file .safety-policy.yml + uses: ./.github/actions/osv-scanner + with: + lockfile: uv.lock - name: Dead code detection with Vulture - if: steps.check-changes.outputs.any_changed == 'true' + # Run even when osv-scanner reports findings so dead-code signal isn't masked by SCA failures. + if: ${{ !cancelled() && steps.check-changes.outputs.any_changed == 'true' }} run: uv run vulture --exclude ".venv,contrib,api,ui" --min-confidence 100 . diff --git a/.github/workflows/ui-security.yml b/.github/workflows/ui-security.yml new file mode 100644 index 0000000000..fdba8d7e30 --- /dev/null +++ b/.github/workflows/ui-security.yml @@ -0,0 +1,75 @@ +name: 'UI: Security' + +on: + push: + branches: + - 'master' + - 'v5.*' + paths: + - 'ui/package.json' + - 'ui/pnpm-lock.yaml' + - '.github/workflows/ui-security.yml' + - '.github/actions/osv-scanner/**' + - '.github/scripts/osv-scan.sh' + pull_request: + branches: + - 'master' + - 'v5.*' + paths: + - 'ui/package.json' + - 'ui/pnpm-lock.yaml' + - '.github/workflows/ui-security.yml' + - '.github/actions/osv-scanner/**' + - '.github/scripts/osv-scan.sh' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: {} + +jobs: + ui-security-scans: + if: github.repository == 'prowler-cloud/prowler' + runs-on: ubuntu-latest + timeout-minutes: 15 + permissions: + contents: read + pull-requests: write # osv-scanner action posts/updates a PR comment with findings + + steps: + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: block + allowed-endpoints: > + github.com:443 + api.github.com:443 + objects.githubusercontent.com:443 + release-assets.githubusercontent.com:443 + api.osv.dev:443 + api.deps.dev:443 + osv-vulnerabilities.storage.googleapis.com:443 + + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + # zizmor: ignore[artipacked] + persist-credentials: true # Required by tj-actions/changed-files to fetch PR branch + + - name: Check for UI dependency changes + id: check-changes + uses: tj-actions/changed-files@22103cc46bda19c2b464ffe86db46df6922fd323 # v47.0.5 + with: + files: | + ui/package.json + ui/pnpm-lock.yaml + .github/workflows/ui-security.yml + .github/actions/osv-scanner/** + .github/scripts/osv-scan.sh + + - name: Dependency vulnerability scan with osv-scanner + if: steps.check-changes.outputs.any_changed == 'true' + uses: ./.github/actions/osv-scanner + with: + lockfile: ui/pnpm-lock.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9d40c5c3e6..dcd4581ef0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -165,16 +165,6 @@ repos: exclude: { glob: ["{contrib,skills}/**", "**/.venv/**", "**/*_test.py"] } priority: 40 - - id: safety - name: safety - description: "Safety is a tool that checks your installed dependencies for known security vulnerabilities" - # Accepted CVEs, severity threshold, and ignore expirations live in .safety-policy.yml - entry: safety check --policy-file .safety-policy.yml - language: system - pass_filenames: false - files: { glob: ["**/pyproject.toml", "**/uv.lock", "**/requirements*.txt", ".safety-policy.yml"] } - priority: 40 - - id: vulture name: vulture description: "Vulture finds unused code in Python programs." diff --git a/.safety-policy.yml b/.safety-policy.yml deleted file mode 100644 index dc94625072..0000000000 --- a/.safety-policy.yml +++ /dev/null @@ -1,58 +0,0 @@ -# Safety policy for `safety check` (Safety CLI 3.x, v2 schema). -# Applied in: .pre-commit-config.yaml, .github/workflows/api-security.yml, -# .github/workflows/sdk-security.yml via `--policy-file`. -# -# Validate: uv run safety validate policy_file --path .safety-policy.yml - -security: - # Scan unpinned requirements too. Prowler pins via uv.lock, so this is - # defensive against accidental unpinned entries. - ignore-unpinned-requirements: False - - # CVSS severity filter. 7 = report only HIGH (7.0–8.9) and CRITICAL (9.0–10.0). - # Reference: 9=CRITICAL only, 7=CRITICAL+HIGH, 4=CRITICAL+HIGH+MEDIUM. - ignore-cvss-severity-below: 7 - - # Unknown severity is unrated, not safe. Keep False so unrated CVEs still fail - # the build and get a human eye. Flip to True only if noise is unmanageable. - ignore-cvss-unknown-severity: False - - # Fail the build when a non-ignored vulnerability is found. - continue-on-vulnerability-error: False - - # Explicit accepted vulnerabilities. Each entry MUST have a reason and an - # expiry. Expired entries fail the scan, forcing re-audit. - ignore-vulnerabilities: - 77744: - reason: "Botocore requires urllib3 1.X. Remove once upgraded to urllib3 2.X." - expires: '2026-10-22' - 77745: - reason: "Botocore requires urllib3 1.X. Remove once upgraded to urllib3 2.X." - expires: '2026-10-22' - 79023: - reason: "knack ReDoS; blocked until azure-cli-core (via cartography) allows knack >=0.13.0." - expires: '2026-10-22' - 79027: - reason: "knack ReDoS; blocked until azure-cli-core (via cartography) allows knack >=0.13.0." - expires: '2026-10-22' - 86217: - reason: "alibabacloud-tea-openapi==0.4.3 blocks upgrade to cryptography >=46.0.0." - expires: '2026-10-22' - 71600: - reason: "CVE-2024-1135 false positive. Fixed in gunicorn 22.0.0; project uses 23.0.0." - expires: '2026-10-22' - 70612: - reason: "TBD - audit required. Reason not documented in prior --ignore list." - expires: '2026-07-22' - 66963: - reason: "TBD - audit required. Reason not documented in prior --ignore list." - expires: '2026-07-22' - 74429: - reason: "TBD - audit required. Reason not documented in prior --ignore list." - expires: '2026-07-22' - 76352: - reason: "TBD - audit required. Reason not documented in prior --ignore list." - expires: '2026-07-22' - 76353: - reason: "TBD - audit required. Reason not documented in prior --ignore list." - expires: '2026-07-22' diff --git a/action.yml b/action.yml index 3b5b8d8bdf..a93c67d4e8 100644 --- a/action.yml +++ b/action.yml @@ -167,7 +167,7 @@ runs: - name: Upload SARIF to GitHub Code Scanning if: always() && inputs.upload-sarif == 'true' && steps.find-sarif.outputs.sarif_path != '' - uses: github/codeql-action/upload-sarif@d4b3ca9fa7f69d38bfcd667bdc45bc373d16277e # v4 + uses: github/codeql-action/upload-sarif@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4 with: sarif_file: ${{ steps.find-sarif.outputs.sarif_path }} category: ${{ inputs.sarif-category }} diff --git a/api/pyproject.toml b/api/pyproject.toml index 07a1b3e1bb..2fd1ebdbc9 100644 --- a/api/pyproject.toml +++ b/api/pyproject.toml @@ -15,7 +15,6 @@ dev = [ "pytest-randomly==3.15.0", "pytest-xdist==3.6.1", "ruff==0.5.0", - "safety==3.7.0", "tqdm==4.67.1", "vulture==2.14", "prek==0.3.9" @@ -393,8 +392,6 @@ constraint-dependencies = [ "ruamel-yaml==0.19.1", "ruff==0.5.0", "s3transfer==0.14.0", - "safety==3.7.0", - "safety-schemas==0.0.16", "scaleway==2.10.3", "scaleway-core==2.10.3", "schema==0.7.5", diff --git a/api/uv.lock b/api/uv.lock index 9a4aea9b43..5e47b532fe 100644 --- a/api/uv.lock +++ b/api/uv.lock @@ -329,8 +329,6 @@ constraints = [ { name = "ruamel-yaml", specifier = "==0.19.1" }, { name = "ruff", specifier = "==0.5.0" }, { name = "s3transfer", specifier = "==0.14.0" }, - { name = "safety", specifier = "==3.7.0" }, - { name = "safety-schemas", specifier = "==0.0.16" }, { name = "scaleway", specifier = "==2.10.3" }, { name = "scaleway-core", specifier = "==2.10.3" }, { name = "schema", specifier = "==0.7.5" }, @@ -1030,18 +1028,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl", hash = "sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373", size = 67615, upload-time = "2025-10-06T13:54:43.17Z" }, ] -[[package]] -name = "authlib" -version = "1.6.9" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "cryptography" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/af/98/00d3dd826d46959ad8e32af2dbb2398868fd9fd0683c26e56d0789bd0e68/authlib-1.6.9.tar.gz", hash = "sha256:d8f2421e7e5980cc1ddb4e32d3f5fa659cfaf60d8eaf3281ebed192e4ab74f04", size = 165134, upload-time = "2026-03-02T07:44:01.998Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/53/23/b65f568ed0c22f1efacb744d2db1a33c8068f384b8c9b482b52ebdbc3ef6/authlib-1.6.9-py2.py3-none-any.whl", hash = "sha256:f08b4c14e08f0861dc18a32357b33fbcfd2ea86cfe3fe149484b4d764c4a0ac3", size = 244197, upload-time = "2026-03-02T07:44:00.307Z" }, -] - [[package]] name = "autopep8" version = "2.3.2" @@ -2511,18 +2497,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/dc/80/12235e5b75bb2c586733280854f131b86051e0bbdfb55349ff70d0f72cf9/dogpile_cache-1.5.0-py3-none-any.whl", hash = "sha256:dc7b47d37844db15e8fdc0243c1b58857a2ddc52a5118237a97127bac200e18d", size = 64447, upload-time = "2025-10-11T17:35:38.573Z" }, ] -[[package]] -name = "dparse" -version = "0.6.4" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "packaging" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/29/ee/96c65e17222b973f0d3d0aa9bad6a59104ca1b0eb5b659c25c2900fccd85/dparse-0.6.4.tar.gz", hash = "sha256:90b29c39e3edc36c6284c82c4132648eaf28a01863eb3c231c2512196132201a", size = 27912, upload-time = "2024-11-08T16:52:06.444Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/56/26/035d1c308882514a1e6ddca27f9d3e570d67a0e293e7b4d910a70c8fe32b/dparse-0.6.4-py3-none-any.whl", hash = "sha256:fbab4d50d54d0e739fbb4dedfc3d92771003a5b9aa8545ca7a7045e3b174af57", size = 11925, upload-time = "2024-11-08T16:52:03.844Z" }, -] - [[package]] name = "drf-extensions" version = "0.8.0" @@ -3318,15 +3292,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/14/2f/967ba146e6d58cf6a652da73885f52fc68001525b4197effc174321d70b4/jmespath-1.1.0-py3-none-any.whl", hash = "sha256:a5663118de4908c91729bea0acadca56526eb2698e83de10cd116ae0f4e97c64", size = 20419, upload-time = "2026-01-22T16:35:24.919Z" }, ] -[[package]] -name = "joblib" -version = "1.5.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/41/f2/d34e8b3a08a9cc79a50b2208a93dce981fe615b64d5a4d4abee421d898df/joblib-1.5.3.tar.gz", hash = "sha256:8561a3269e6801106863fd0d6d84bb737be9e7631e33aaed3fb9ce5953688da3", size = 331603, upload-time = "2025-12-15T08:41:46.427Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7b/91/984aca2ec129e2757d1e4e3c81c3fcda9d0f85b74670a094cc443d9ee949/joblib-1.5.3-py3-none-any.whl", hash = "sha256:5fc3c5039fc5ca8c0276333a188bbd59d6b7ab37fe6632daa76bc7f9ec18e713", size = 309071, upload-time = "2025-12-15T08:41:44.973Z" }, -] - [[package]] name = "jsonpatch" version = "1.33" @@ -3990,21 +3955,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c", size = 5195, upload-time = "2024-01-21T14:25:17.223Z" }, ] -[[package]] -name = "nltk" -version = "3.9.4" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "click" }, - { name = "joblib" }, - { name = "regex" }, - { name = "tqdm" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/74/a1/b3b4adf15585a5bc4c357adde150c01ebeeb642173ded4d871e89468767c/nltk-3.9.4.tar.gz", hash = "sha256:ed03bc098a40481310320808b2db712d95d13ca65b27372f8a403949c8b523d0", size = 2946864, upload-time = "2026-03-24T06:13:40.641Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9d/91/04e965f8e717ba0ab4bdca5c112deeab11c9e750d94c4d4602f050295d39/nltk-3.9.4-py3-none-any.whl", hash = "sha256:f2fa301c3a12718ce4a0e9305c5675299da5ad9e26068218b69d692fda84828f", size = 1552087, upload-time = "2026-03-24T06:13:38.47Z" }, -] - [[package]] name = "numpy" version = "2.0.2" @@ -4596,7 +4546,6 @@ dev = [ { name = "pytest-randomly" }, { name = "pytest-xdist" }, { name = "ruff" }, - { name = "safety" }, { name = "tqdm" }, { name = "vulture" }, ] @@ -4661,7 +4610,6 @@ dev = [ { name = "pytest-randomly", specifier = "==3.15.0" }, { name = "pytest-xdist", specifier = "==3.6.1" }, { name = "ruff", specifier = "==0.5.0" }, - { name = "safety", specifier = "==3.7.0" }, { name = "tqdm", specifier = "==4.67.1" }, { name = "vulture", specifier = "==2.14" }, ] @@ -5257,46 +5205,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl", hash = "sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231", size = 26766, upload-time = "2025-10-13T15:30:47.625Z" }, ] -[[package]] -name = "regex" -version = "2026.1.15" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0b/86/07d5056945f9ec4590b518171c4254a5925832eb727b56d3c38a7476f316/regex-2026.1.15.tar.gz", hash = "sha256:164759aa25575cbc0651bef59a0b18353e54300d79ace8084c818ad8ac72b7d5", size = 414811, upload-time = "2026-01-14T23:18:02.775Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d0/c9/0c80c96eab96948363d270143138d671d5731c3a692b417629bf3492a9d6/regex-2026.1.15-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1ae6020fb311f68d753b7efa9d4b9a5d47a5d6466ea0d5e3b5a471a960ea6e4a", size = 488168, upload-time = "2026-01-14T23:14:16.129Z" }, - { url = "https://files.pythonhosted.org/packages/17/f0/271c92f5389a552494c429e5cc38d76d1322eb142fb5db3c8ccc47751468/regex-2026.1.15-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:eddf73f41225942c1f994914742afa53dc0d01a6e20fe14b878a1b1edc74151f", size = 290636, upload-time = "2026-01-14T23:14:17.715Z" }, - { url = "https://files.pythonhosted.org/packages/a0/f9/5f1fd077d106ca5655a0f9ff8f25a1ab55b92128b5713a91ed7134ff688e/regex-2026.1.15-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e8cd52557603f5c66a548f69421310886b28b7066853089e1a71ee710e1cdc1", size = 288496, upload-time = "2026-01-14T23:14:19.326Z" }, - { url = "https://files.pythonhosted.org/packages/b5/e1/8f43b03a4968c748858ec77f746c286d81f896c2e437ccf050ebc5d3128c/regex-2026.1.15-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5170907244b14303edc5978f522f16c974f32d3aa92109fabc2af52411c9433b", size = 793503, upload-time = "2026-01-14T23:14:20.922Z" }, - { url = "https://files.pythonhosted.org/packages/8d/4e/a39a5e8edc5377a46a7c875c2f9a626ed3338cb3bb06931be461c3e1a34a/regex-2026.1.15-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2748c1ec0663580b4510bd89941a31560b4b439a0b428b49472a3d9944d11cd8", size = 860535, upload-time = "2026-01-14T23:14:22.405Z" }, - { url = "https://files.pythonhosted.org/packages/dc/1c/9dce667a32a9477f7a2869c1c767dc00727284a9fa3ff5c09a5c6c03575e/regex-2026.1.15-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2f2775843ca49360508d080eaa87f94fa248e2c946bbcd963bb3aae14f333413", size = 907225, upload-time = "2026-01-14T23:14:23.897Z" }, - { url = "https://files.pythonhosted.org/packages/a4/3c/87ca0a02736d16b6262921425e84b48984e77d8e4e572c9072ce96e66c30/regex-2026.1.15-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d9ea2604370efc9a174c1b5dcc81784fb040044232150f7f33756049edfc9026", size = 800526, upload-time = "2026-01-14T23:14:26.039Z" }, - { url = "https://files.pythonhosted.org/packages/4b/ff/647d5715aeea7c87bdcbd2f578f47b415f55c24e361e639fe8c0cc88878f/regex-2026.1.15-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0dcd31594264029b57bf16f37fd7248a70b3b764ed9e0839a8f271b2d22c0785", size = 773446, upload-time = "2026-01-14T23:14:28.109Z" }, - { url = "https://files.pythonhosted.org/packages/af/89/bf22cac25cb4ba0fe6bff52ebedbb65b77a179052a9d6037136ae93f42f4/regex-2026.1.15-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c08c1f3e34338256732bd6938747daa3c0d5b251e04b6e43b5813e94d503076e", size = 783051, upload-time = "2026-01-14T23:14:29.929Z" }, - { url = "https://files.pythonhosted.org/packages/1e/f4/6ed03e71dca6348a5188363a34f5e26ffd5db1404780288ff0d79513bce4/regex-2026.1.15-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e43a55f378df1e7a4fa3547c88d9a5a9b7113f653a66821bcea4718fe6c58763", size = 854485, upload-time = "2026-01-14T23:14:31.366Z" }, - { url = "https://files.pythonhosted.org/packages/d9/9a/8e8560bd78caded8eb137e3e47612430a05b9a772caf60876435192d670a/regex-2026.1.15-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:f82110ab962a541737bd0ce87978d4c658f06e7591ba899192e2712a517badbb", size = 762195, upload-time = "2026-01-14T23:14:32.802Z" }, - { url = "https://files.pythonhosted.org/packages/38/6b/61fc710f9aa8dfcd764fe27d37edfaa023b1a23305a0d84fccd5adb346ea/regex-2026.1.15-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:27618391db7bdaf87ac6c92b31e8f0dfb83a9de0075855152b720140bda177a2", size = 845986, upload-time = "2026-01-14T23:14:34.898Z" }, - { url = "https://files.pythonhosted.org/packages/fd/2e/fbee4cb93f9d686901a7ca8d94285b80405e8c34fe4107f63ffcbfb56379/regex-2026.1.15-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bfb0d6be01fbae8d6655c8ca21b3b72458606c4aec9bbc932db758d47aba6db1", size = 788992, upload-time = "2026-01-14T23:14:37.116Z" }, - { url = "https://files.pythonhosted.org/packages/ed/14/3076348f3f586de64b1ab75a3fbabdaab7684af7f308ad43be7ef1849e55/regex-2026.1.15-cp311-cp311-win32.whl", hash = "sha256:b10e42a6de0e32559a92f2f8dc908478cc0fa02838d7dbe764c44dca3fa13569", size = 265893, upload-time = "2026-01-14T23:14:38.426Z" }, - { url = "https://files.pythonhosted.org/packages/0f/19/772cf8b5fc803f5c89ba85d8b1870a1ca580dc482aa030383a9289c82e44/regex-2026.1.15-cp311-cp311-win_amd64.whl", hash = "sha256:e9bf3f0bbdb56633c07d7116ae60a576f846efdd86a8848f8d62b749e1209ca7", size = 277840, upload-time = "2026-01-14T23:14:39.785Z" }, - { url = "https://files.pythonhosted.org/packages/78/84/d05f61142709474da3c0853222d91086d3e1372bcdab516c6fd8d80f3297/regex-2026.1.15-cp311-cp311-win_arm64.whl", hash = "sha256:41aef6f953283291c4e4e6850607bd71502be67779586a61472beacb315c97ec", size = 270374, upload-time = "2026-01-14T23:14:41.592Z" }, - { url = "https://files.pythonhosted.org/packages/92/81/10d8cf43c807d0326efe874c1b79f22bfb0fb226027b0b19ebc26d301408/regex-2026.1.15-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:4c8fcc5793dde01641a35905d6731ee1548f02b956815f8f1cab89e515a5bdf1", size = 489398, upload-time = "2026-01-14T23:14:43.741Z" }, - { url = "https://files.pythonhosted.org/packages/90/b0/7c2a74e74ef2a7c32de724658a69a862880e3e4155cba992ba04d1c70400/regex-2026.1.15-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:bfd876041a956e6a90ad7cdb3f6a630c07d491280bfeed4544053cd434901681", size = 291339, upload-time = "2026-01-14T23:14:45.183Z" }, - { url = "https://files.pythonhosted.org/packages/19/4d/16d0773d0c818417f4cc20aa0da90064b966d22cd62a8c46765b5bd2d643/regex-2026.1.15-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9250d087bc92b7d4899ccd5539a1b2334e44eee85d848c4c1aef8e221d3f8c8f", size = 289003, upload-time = "2026-01-14T23:14:47.25Z" }, - { url = "https://files.pythonhosted.org/packages/c6/e4/1fc4599450c9f0863d9406e944592d968b8d6dfd0d552a7d569e43bceada/regex-2026.1.15-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c8a154cf6537ebbc110e24dabe53095e714245c272da9c1be05734bdad4a61aa", size = 798656, upload-time = "2026-01-14T23:14:48.77Z" }, - { url = "https://files.pythonhosted.org/packages/b2/e6/59650d73a73fa8a60b3a590545bfcf1172b4384a7df2e7fe7b9aab4e2da9/regex-2026.1.15-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8050ba2e3ea1d8731a549e83c18d2f0999fbc99a5f6bd06b4c91449f55291804", size = 864252, upload-time = "2026-01-14T23:14:50.528Z" }, - { url = "https://files.pythonhosted.org/packages/6e/ab/1d0f4d50a1638849a97d731364c9a80fa304fec46325e48330c170ee8e80/regex-2026.1.15-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0bf065240704cb8951cc04972cf107063917022511273e0969bdb34fc173456c", size = 912268, upload-time = "2026-01-14T23:14:52.952Z" }, - { url = "https://files.pythonhosted.org/packages/dd/df/0d722c030c82faa1d331d1921ee268a4e8fb55ca8b9042c9341c352f17fa/regex-2026.1.15-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c32bef3e7aeee75746748643667668ef941d28b003bfc89994ecf09a10f7a1b5", size = 803589, upload-time = "2026-01-14T23:14:55.182Z" }, - { url = "https://files.pythonhosted.org/packages/66/23/33289beba7ccb8b805c6610a8913d0131f834928afc555b241caabd422a9/regex-2026.1.15-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d5eaa4a4c5b1906bd0d2508d68927f15b81821f85092e06f1a34a4254b0e1af3", size = 775700, upload-time = "2026-01-14T23:14:56.707Z" }, - { url = "https://files.pythonhosted.org/packages/e7/65/bf3a42fa6897a0d3afa81acb25c42f4b71c274f698ceabd75523259f6688/regex-2026.1.15-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:86c1077a3cc60d453d4084d5b9649065f3bf1184e22992bd322e1f081d3117fb", size = 787928, upload-time = "2026-01-14T23:14:58.312Z" }, - { url = "https://files.pythonhosted.org/packages/f4/f5/13bf65864fc314f68cdd6d8ca94adcab064d4d39dbd0b10fef29a9da48fc/regex-2026.1.15-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:2b091aefc05c78d286657cd4db95f2e6313375ff65dcf085e42e4c04d9c8d410", size = 858607, upload-time = "2026-01-14T23:15:00.657Z" }, - { url = "https://files.pythonhosted.org/packages/a3/31/040e589834d7a439ee43fb0e1e902bc81bd58a5ba81acffe586bb3321d35/regex-2026.1.15-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:57e7d17f59f9ebfa9667e6e5a1c0127b96b87cb9cede8335482451ed00788ba4", size = 763729, upload-time = "2026-01-14T23:15:02.248Z" }, - { url = "https://files.pythonhosted.org/packages/9b/84/6921e8129687a427edf25a34a5594b588b6d88f491320b9de5b6339a4fcb/regex-2026.1.15-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:c6c4dcdfff2c08509faa15d36ba7e5ef5fcfab25f1e8f85a0c8f45bc3a30725d", size = 850697, upload-time = "2026-01-14T23:15:03.878Z" }, - { url = "https://files.pythonhosted.org/packages/8a/87/3d06143d4b128f4229158f2de5de6c8f2485170c7221e61bf381313314b2/regex-2026.1.15-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:cf8ff04c642716a7f2048713ddc6278c5fd41faa3b9cab12607c7abecd012c22", size = 789849, upload-time = "2026-01-14T23:15:06.102Z" }, - { url = "https://files.pythonhosted.org/packages/77/69/c50a63842b6bd48850ebc7ab22d46e7a2a32d824ad6c605b218441814639/regex-2026.1.15-cp312-cp312-win32.whl", hash = "sha256:82345326b1d8d56afbe41d881fdf62f1926d7264b2fc1537f99ae5da9aad7913", size = 266279, upload-time = "2026-01-14T23:15:07.678Z" }, - { url = "https://files.pythonhosted.org/packages/f2/36/39d0b29d087e2b11fd8191e15e81cce1b635fcc845297c67f11d0d19274d/regex-2026.1.15-cp312-cp312-win_amd64.whl", hash = "sha256:4def140aa6156bc64ee9912383d4038f3fdd18fee03a6f222abd4de6357ce42a", size = 277166, upload-time = "2026-01-14T23:15:09.257Z" }, - { url = "https://files.pythonhosted.org/packages/28/32/5b8e476a12262748851fa8ab1b0be540360692325975b094e594dfebbb52/regex-2026.1.15-cp312-cp312-win_arm64.whl", hash = "sha256:c6c565d9a6e1a8d783c1948937ffc377dd5771e83bd56de8317c450a954d2056", size = 270415, upload-time = "2026-01-14T23:15:10.743Z" }, -] - [[package]] name = "reportlab" version = "4.4.10" @@ -5448,15 +5356,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/64/8d/0133e4eb4beed9e425d9a98ed6e081a55d195481b7632472be1af08d2f6b/rsa-4.9.1-py3-none-any.whl", hash = "sha256:68635866661c6836b8d39430f97a996acbd61bfa49406748ea243539fe239762", size = 34696, upload-time = "2025-04-16T09:51:17.142Z" }, ] -[[package]] -name = "ruamel-yaml" -version = "0.19.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c7/3b/ebda527b56beb90cb7652cb1c7e4f91f48649fbcd8d2eb2fb6e77cd3329b/ruamel_yaml-0.19.1.tar.gz", hash = "sha256:53eb66cd27849eff968ebf8f0bf61f46cdac2da1d1f3576dd4ccee9b25c31993", size = 142709, upload-time = "2026-01-02T16:50:31.84Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b8/0c/51f6841f1d84f404f92463fc2b1ba0da357ca1e3db6b7fbda26956c3b82a/ruamel_yaml-0.19.1-py3-none-any.whl", hash = "sha256:27592957fedf6e0b62f281e96effd28043345e0e66001f97683aa9a40c667c93", size = 118102, upload-time = "2026-01-02T16:50:29.201Z" }, -] - [[package]] name = "ruff" version = "0.5.0" @@ -5494,50 +5393,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/48/f0/ae7ca09223a81a1d890b2557186ea015f6e0502e9b8cb8e1813f1d8cfa4e/s3transfer-0.14.0-py3-none-any.whl", hash = "sha256:ea3b790c7077558ed1f02a3072fb3cb992bbbd253392f4b6e9e8976941c7d456", size = 85712, upload-time = "2025-09-09T19:23:30.041Z" }, ] -[[package]] -name = "safety" -version = "3.7.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "authlib" }, - { name = "click" }, - { name = "dparse" }, - { name = "filelock" }, - { name = "httpx" }, - { name = "jinja2" }, - { name = "marshmallow" }, - { name = "nltk" }, - { name = "packaging" }, - { name = "pydantic" }, - { name = "requests" }, - { name = "ruamel-yaml" }, - { name = "safety-schemas" }, - { name = "tenacity" }, - { name = "tomlkit" }, - { name = "typer" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/6f/e8/1cfffa0d8836de8aa31f4fa7fdeb892c7cfa97cd555039ad5df71ce0e968/safety-3.7.0.tar.gz", hash = "sha256:daec15a393cafc32b846b7ef93f9c952a1708863e242341ab5bde2e4beabb54e", size = 330538, upload-time = "2025-11-06T20:10:15.067Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/89/55/c4b2058ca346e58124ba082a3596e30dc1f5793710f8173156c7c2d77048/safety-3.7.0-py3-none-any.whl", hash = "sha256:65e71db45eb832e8840e3456333d44c23927423753d5610596a09e909a66d2bf", size = 312436, upload-time = "2025-11-06T20:10:13.576Z" }, -] - -[[package]] -name = "safety-schemas" -version = "0.0.16" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "dparse" }, - { name = "packaging" }, - { name = "pydantic" }, - { name = "ruamel-yaml" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/c2/ef/0e07dfdb4104c4e42ae9fc6e8a0da7be2d72ac2ee198b32f7500796de8f3/safety_schemas-0.0.16.tar.gz", hash = "sha256:3bb04d11bd4b5cc79f9fa183c658a6a8cf827a9ceec443a5ffa6eed38a50a24e", size = 54815, upload-time = "2025-09-16T14:35:31.973Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/84/a2/7840cc32890ce4b84668d3d9dfe15a48355b683ae3fb627ac97ac5a4265f/safety_schemas-0.0.16-py3-none-any.whl", hash = "sha256:6760515d3fd1e6535b251cd73014bd431d12fe0bfb8b6e8880a9379b5ab7aa44", size = 39292, upload-time = "2025-09-16T14:35:32.84Z" }, -] - [[package]] name = "scaleway" version = "2.10.3" diff --git a/pyproject.toml b/pyproject.toml index b2fd7286aa..94249c1120 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,7 +22,6 @@ dev = [ "pytest-env==1.1.5", "pytest-randomly==3.16.0", "pytest-xdist==3.6.1", - "safety==3.7.0", "vulture==2.14" ] diff --git a/scripts/setup-git-hooks.sh b/scripts/setup-git-hooks.sh index d01af21893..c1d930b20f 100755 --- a/scripts/setup-git-hooks.sh +++ b/scripts/setup-git-hooks.sh @@ -32,7 +32,7 @@ fi echo "" -# Full setup requires uv for system hooks (pylint, bandit, safety, vulture, trufflehog) +# Full setup requires uv for system hooks (pylint, bandit, vulture, trufflehog) # These are installed as Python dev dependencies and used by local hooks in .pre-commit-config.yaml if command -v uv &>/dev/null && [ -f "pyproject.toml" ]; then if uv run prek --version &>/dev/null 2>&1; then @@ -50,7 +50,7 @@ elif command -v prek &>/dev/null; then prek install --overwrite echo "" echo -e "${YELLOW}⚠️ Warning: Some hooks require Python tools installed via uv:${NC}" - echo -e " pylint, bandit, safety, vulture, trufflehog" + echo -e " pylint, bandit, vulture, trufflehog" echo -e " These hooks will be skipped unless you install them or run:" echo -e " ${GREEN}uv sync${NC}" else diff --git a/uv.lock b/uv.lock index bf3bc73496..6194161723 100644 --- a/uv.lock +++ b/uv.lock @@ -521,15 +521,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/5a/a9/5a83b6547f88514f16098c7f8418b1a9490a92e644481662e9ebc3a98923/aliyun_log_fastpb-0.3.0-cp37-abi3-win_amd64.whl", hash = "sha256:522b734e17eca7797235f297ff6a607137d2be92034778bb041ea061cd9cd9ba", size = 125709, upload-time = "2026-04-28T03:06:47.405Z" }, ] -[[package]] -name = "annotated-doc" -version = "0.0.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/57/ba/046ceea27344560984e26a590f90bc7f4a75b06701f653222458922b558c/annotated_doc-0.0.4.tar.gz", hash = "sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4", size = 7288, upload-time = "2025-11-10T22:07:42.062Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320", size = 5303, upload-time = "2025-11-10T22:07:40.673Z" }, -] - [[package]] name = "annotated-types" version = "0.7.0" @@ -604,19 +595,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/64/b4/17d4b0b2a2dc85a6df63d1157e028ed19f90d4cd97c36717afef2bc2f395/attrs-26.1.0-py3-none-any.whl", hash = "sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309", size = 67548, upload-time = "2026-03-19T14:22:23.645Z" }, ] -[[package]] -name = "authlib" -version = "1.7.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "cryptography" }, - { name = "joserfc" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/36/98/7d93f30d029643c0275dbc0bd6d5a6f670661ee6c9a94d93af7ab4887600/authlib-1.7.2.tar.gz", hash = "sha256:2cea25fefcd4e7173bdf1372c0afc265c8034b23a8cd5dcb6a9164b826c64231", size = 176511, upload-time = "2026-05-06T08:10:23.116Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/fb/95/adcb68e20c34162e9135f370d6e31737719c2b6f94bc953fe7ed1f10fe21/authlib-1.7.2-py2.py3-none-any.whl", hash = "sha256:3e1faedc9d87e7d56a164eca3ccb6ace0d61b94abe83e92242f8dc8bba9b4a9f", size = 259548, upload-time = "2026-05-06T08:10:21.436Z" }, -] - [[package]] name = "aws-sam-translator" version = "1.109.0" @@ -1084,40 +1062,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/74/3c/3814aba90a63e84c7de0eb6fdf67bd1a9115ac5f99ec5b7a817a5d5278ec/azure_storage_blob-12.24.1-py3-none-any.whl", hash = "sha256:77fb823fdbac7f3c11f7d86a5892e2f85e161e8440a7489babe2195bf248f09e", size = 408432, upload-time = "2025-01-22T21:27:23.082Z" }, ] -[[package]] -name = "backports-datetime-fromisoformat" -version = "2.0.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/71/81/eff3184acb1d9dc3ce95a98b6f3c81a49b4be296e664db8e1c2eeabef3d9/backports_datetime_fromisoformat-2.0.3.tar.gz", hash = "sha256:b58edc8f517b66b397abc250ecc737969486703a66eb97e01e6d51291b1a139d", size = 23588, upload-time = "2024-12-28T20:18:15.017Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/42/4b/d6b051ca4b3d76f23c2c436a9669f3be616b8cf6461a7e8061c7c4269642/backports_datetime_fromisoformat-2.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5f681f638f10588fa3c101ee9ae2b63d3734713202ddfcfb6ec6cea0778a29d4", size = 27561, upload-time = "2024-12-28T20:16:47.974Z" }, - { url = "https://files.pythonhosted.org/packages/6d/40/e39b0d471e55eb1b5c7c81edab605c02f71c786d59fb875f0a6f23318747/backports_datetime_fromisoformat-2.0.3-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:cd681460e9142f1249408e5aee6d178c6d89b49e06d44913c8fdfb6defda8d1c", size = 34448, upload-time = "2024-12-28T20:16:50.712Z" }, - { url = "https://files.pythonhosted.org/packages/f2/28/7a5c87c5561d14f1c9af979231fdf85d8f9fad7a95ff94e56d2205e2520a/backports_datetime_fromisoformat-2.0.3-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:ee68bc8735ae5058695b76d3bb2aee1d137c052a11c8303f1e966aa23b72b65b", size = 27093, upload-time = "2024-12-28T20:16:52.994Z" }, - { url = "https://files.pythonhosted.org/packages/80/ba/f00296c5c4536967c7d1136107fdb91c48404fe769a4a6fd5ab045629af8/backports_datetime_fromisoformat-2.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8273fe7932db65d952a43e238318966eab9e49e8dd546550a41df12175cc2be4", size = 52836, upload-time = "2024-12-28T20:16:55.283Z" }, - { url = "https://files.pythonhosted.org/packages/e3/92/bb1da57a069ddd601aee352a87262c7ae93467e66721d5762f59df5021a6/backports_datetime_fromisoformat-2.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39d57ea50aa5a524bb239688adc1d1d824c31b6094ebd39aa164d6cadb85de22", size = 52798, upload-time = "2024-12-28T20:16:56.64Z" }, - { url = "https://files.pythonhosted.org/packages/df/ef/b6cfd355982e817ccdb8d8d109f720cab6e06f900784b034b30efa8fa832/backports_datetime_fromisoformat-2.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ac6272f87693e78209dc72e84cf9ab58052027733cd0721c55356d3c881791cf", size = 52891, upload-time = "2024-12-28T20:16:58.887Z" }, - { url = "https://files.pythonhosted.org/packages/37/39/b13e3ae8a7c5d88b68a6e9248ffe7066534b0cfe504bf521963e61b6282d/backports_datetime_fromisoformat-2.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:44c497a71f80cd2bcfc26faae8857cf8e79388e3d5fbf79d2354b8c360547d58", size = 52955, upload-time = "2024-12-28T20:17:00.028Z" }, - { url = "https://files.pythonhosted.org/packages/1e/e4/70cffa3ce1eb4f2ff0c0d6f5d56285aacead6bd3879b27a2ba57ab261172/backports_datetime_fromisoformat-2.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:6335a4c9e8af329cb1ded5ab41a666e1448116161905a94e054f205aa6d263bc", size = 29323, upload-time = "2024-12-28T20:17:01.125Z" }, - { url = "https://files.pythonhosted.org/packages/62/f5/5bc92030deadf34c365d908d4533709341fb05d0082db318774fdf1b2bcb/backports_datetime_fromisoformat-2.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e2e4b66e017253cdbe5a1de49e0eecff3f66cd72bcb1229d7db6e6b1832c0443", size = 27626, upload-time = "2024-12-28T20:17:03.448Z" }, - { url = "https://files.pythonhosted.org/packages/28/45/5885737d51f81dfcd0911dd5c16b510b249d4c4cf6f4a991176e0358a42a/backports_datetime_fromisoformat-2.0.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:43e2d648e150777e13bbc2549cc960373e37bf65bd8a5d2e0cef40e16e5d8dd0", size = 34588, upload-time = "2024-12-28T20:17:04.459Z" }, - { url = "https://files.pythonhosted.org/packages/bc/6d/bd74de70953f5dd3e768c8fc774af942af0ce9f211e7c38dd478fa7ea910/backports_datetime_fromisoformat-2.0.3-cp311-cp311-macosx_11_0_x86_64.whl", hash = "sha256:4ce6326fd86d5bae37813c7bf1543bae9e4c215ec6f5afe4c518be2635e2e005", size = 27162, upload-time = "2024-12-28T20:17:06.752Z" }, - { url = "https://files.pythonhosted.org/packages/47/ba/1d14b097f13cce45b2b35db9898957578b7fcc984e79af3b35189e0d332f/backports_datetime_fromisoformat-2.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7c8fac333bf860208fd522a5394369ee3c790d0aa4311f515fcc4b6c5ef8d75", size = 54482, upload-time = "2024-12-28T20:17:08.15Z" }, - { url = "https://files.pythonhosted.org/packages/25/e9/a2a7927d053b6fa148b64b5e13ca741ca254c13edca99d8251e9a8a09cfe/backports_datetime_fromisoformat-2.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24a4da5ab3aa0cc293dc0662a0c6d1da1a011dc1edcbc3122a288cfed13a0b45", size = 54362, upload-time = "2024-12-28T20:17:10.605Z" }, - { url = "https://files.pythonhosted.org/packages/c1/99/394fb5e80131a7d58c49b89e78a61733a9994885804a0bb582416dd10c6f/backports_datetime_fromisoformat-2.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:58ea11e3bf912bd0a36b0519eae2c5b560b3cb972ea756e66b73fb9be460af01", size = 54162, upload-time = "2024-12-28T20:17:12.301Z" }, - { url = "https://files.pythonhosted.org/packages/88/25/1940369de573c752889646d70b3fe8645e77b9e17984e72a554b9b51ffc4/backports_datetime_fromisoformat-2.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:8a375c7dbee4734318714a799b6c697223e4bbb57232af37fbfff88fb48a14c6", size = 54118, upload-time = "2024-12-28T20:17:13.609Z" }, - { url = "https://files.pythonhosted.org/packages/b7/46/f275bf6c61683414acaf42b2df7286d68cfef03e98b45c168323d7707778/backports_datetime_fromisoformat-2.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:ac677b1664c4585c2e014739f6678137c8336815406052349c85898206ec7061", size = 29329, upload-time = "2024-12-28T20:17:16.124Z" }, - { url = "https://files.pythonhosted.org/packages/a2/0f/69bbdde2e1e57c09b5f01788804c50e68b29890aada999f2b1a40519def9/backports_datetime_fromisoformat-2.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:66ce47ee1ba91e146149cf40565c3d750ea1be94faf660ca733d8601e0848147", size = 27630, upload-time = "2024-12-28T20:17:19.442Z" }, - { url = "https://files.pythonhosted.org/packages/d5/1d/1c84a50c673c87518b1adfeafcfd149991ed1f7aedc45d6e5eac2f7d19d7/backports_datetime_fromisoformat-2.0.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:8b7e069910a66b3bba61df35b5f879e5253ff0821a70375b9daf06444d046fa4", size = 34707, upload-time = "2024-12-28T20:17:21.79Z" }, - { url = "https://files.pythonhosted.org/packages/71/44/27eae384e7e045cda83f70b551d04b4a0b294f9822d32dea1cbf1592de59/backports_datetime_fromisoformat-2.0.3-cp312-cp312-macosx_11_0_x86_64.whl", hash = "sha256:a3b5d1d04a9e0f7b15aa1e647c750631a873b298cdd1255687bb68779fe8eb35", size = 27280, upload-time = "2024-12-28T20:17:24.503Z" }, - { url = "https://files.pythonhosted.org/packages/a7/7a/a4075187eb6bbb1ff6beb7229db5f66d1070e6968abeb61e056fa51afa5e/backports_datetime_fromisoformat-2.0.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec1b95986430e789c076610aea704db20874f0781b8624f648ca9fb6ef67c6e1", size = 55094, upload-time = "2024-12-28T20:17:25.546Z" }, - { url = "https://files.pythonhosted.org/packages/71/03/3fced4230c10af14aacadc195fe58e2ced91d011217b450c2e16a09a98c8/backports_datetime_fromisoformat-2.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffe5f793db59e2f1d45ec35a1cf51404fdd69df9f6952a0c87c3060af4c00e32", size = 55605, upload-time = "2024-12-28T20:17:29.208Z" }, - { url = "https://files.pythonhosted.org/packages/f6/0a/4b34a838c57bd16d3e5861ab963845e73a1041034651f7459e9935289cfd/backports_datetime_fromisoformat-2.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:620e8e73bd2595dfff1b4d256a12b67fce90ece3de87b38e1dde46b910f46f4d", size = 55353, upload-time = "2024-12-28T20:17:32.433Z" }, - { url = "https://files.pythonhosted.org/packages/d9/68/07d13c6e98e1cad85606a876367ede2de46af859833a1da12c413c201d78/backports_datetime_fromisoformat-2.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4cf9c0a985d68476c1cabd6385c691201dda2337d7453fb4da9679ce9f23f4e7", size = 55298, upload-time = "2024-12-28T20:17:34.919Z" }, - { url = "https://files.pythonhosted.org/packages/60/33/45b4d5311f42360f9b900dea53ab2bb20a3d61d7f9b7c37ddfcb3962f86f/backports_datetime_fromisoformat-2.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:d144868a73002e6e2e6fef72333e7b0129cecdd121aa8f1edba7107fd067255d", size = 29375, upload-time = "2024-12-28T20:17:36.018Z" }, - { url = "https://files.pythonhosted.org/packages/be/03/7eaa9f9bf290395d57fd30d7f1f2f9dff60c06a31c237dc2beb477e8f899/backports_datetime_fromisoformat-2.0.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90e202e72a3d5aae673fcc8c9a4267d56b2f532beeb9173361293625fe4d2039", size = 28980, upload-time = "2024-12-28T20:18:06.554Z" }, - { url = "https://files.pythonhosted.org/packages/47/80/a0ecf33446c7349e79f54cc532933780341d20cff0ee12b5bfdcaa47067e/backports_datetime_fromisoformat-2.0.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2df98ef1b76f5a58bb493dda552259ba60c3a37557d848e039524203951c9f06", size = 28449, upload-time = "2024-12-28T20:18:07.77Z" }, -] - [[package]] name = "bandit" version = "1.8.3" @@ -1623,19 +1567,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/dc/80/12235e5b75bb2c586733280854f131b86051e0bbdfb55349ff70d0f72cf9/dogpile_cache-1.5.0-py3-none-any.whl", hash = "sha256:dc7b47d37844db15e8fdc0243c1b58857a2ddc52a5118237a97127bac200e18d", size = 64447, upload-time = "2025-10-11T17:35:38.573Z" }, ] -[[package]] -name = "dparse" -version = "0.6.4" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "packaging" }, - { name = "tomli", marker = "python_full_version < '3.11'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/29/ee/96c65e17222b973f0d3d0aa9bad6a59104ca1b0eb5b659c25c2900fccd85/dparse-0.6.4.tar.gz", hash = "sha256:90b29c39e3edc36c6284c82c4132648eaf28a01863eb3c231c2512196132201a", size = 27912, upload-time = "2024-11-08T16:52:06.444Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/56/26/035d1c308882514a1e6ddca27f9d3e570d67a0e293e7b4d910a70c8fe32b/dparse-0.6.4-py3-none-any.whl", hash = "sha256:fbab4d50d54d0e739fbb4dedfc3d92771003a5b9aa8545ca7a7045e3b174af57", size = 11925, upload-time = "2024-11-08T16:52:03.844Z" }, -] - [[package]] name = "dulwich" version = "0.23.0" @@ -2084,15 +2015,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/14/2f/967ba146e6d58cf6a652da73885f52fc68001525b4197effc174321d70b4/jmespath-1.1.0-py3-none-any.whl", hash = "sha256:a5663118de4908c91729bea0acadca56526eb2698e83de10cd116ae0f4e97c64", size = 20419, upload-time = "2026-01-22T16:35:24.919Z" }, ] -[[package]] -name = "joblib" -version = "1.5.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/41/f2/d34e8b3a08a9cc79a50b2208a93dce981fe615b64d5a4d4abee421d898df/joblib-1.5.3.tar.gz", hash = "sha256:8561a3269e6801106863fd0d6d84bb737be9e7631e33aaed3fb9ce5953688da3", size = 331603, upload-time = "2025-12-15T08:41:46.427Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7b/91/984aca2ec129e2757d1e4e3c81c3fcda9d0f85b74670a094cc443d9ee949/joblib-1.5.3-py3-none-any.whl", hash = "sha256:5fc3c5039fc5ca8c0276333a188bbd59d6b7ab37fe6632daa76bc7f9ec18e713", size = 309071, upload-time = "2025-12-15T08:41:44.973Z" }, -] - [[package]] name = "joserfc" version = "1.6.5" @@ -2350,19 +2272,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e5/f1/216fc1bbfd74011693a4fd837e7026152e89c4bcf3e77b6692fba9923123/markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f", size = 13906, upload-time = "2025-09-27T18:36:40.689Z" }, ] -[[package]] -name = "marshmallow" -version = "4.3.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "backports-datetime-fromisoformat", marker = "python_full_version < '3.11'" }, - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/25/7e/1dbd4096eb7c148cd2841841916f78820bb85a4d80a0c25c02d30815a7fb/marshmallow-4.3.0.tar.gz", hash = "sha256:fb43c53b3fe240b8f6af37223d6ef1636f927ad9bea8ab323afad95dff090880", size = 224485, upload-time = "2026-04-03T21:46:32.72Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f4/e0/ff24e25218bb59eb6290a530cea40651b14068b6e3659b20f9c175179632/marshmallow-4.3.0-py3-none-any.whl", hash = "sha256:46c4fe6984707e3cbd485dfebbf0a59874f58d695aad05c1668d15e8c6e13b46", size = 49148, upload-time = "2026-04-03T21:46:31.241Z" }, -] - [[package]] name = "mccabe" version = "0.7.0" @@ -2731,21 +2640,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl", hash = "sha256:d47fbf302e7d9cbbb9e2555a0d267983d2aa476bac30e90dfbe5669bd57f3762", size = 2068504, upload-time = "2025-12-08T17:02:38.159Z" }, ] -[[package]] -name = "nltk" -version = "3.9.4" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "click" }, - { name = "joblib" }, - { name = "regex" }, - { name = "tqdm" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/74/a1/b3b4adf15585a5bc4c357adde150c01ebeeb642173ded4d871e89468767c/nltk-3.9.4.tar.gz", hash = "sha256:ed03bc098a40481310320808b2db712d95d13ca65b27372f8a403949c8b523d0", size = 2946864, upload-time = "2026-03-24T06:13:40.641Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9d/91/04e965f8e717ba0ab4bdca5c112deeab11c9e750d94c4d4602f050295d39/nltk-3.9.4-py3-none-any.whl", hash = "sha256:f2fa301c3a12718ce4a0e9305c5675299da5ad9e26068218b69d692fda84828f", size = 1552087, upload-time = "2026-03-24T06:13:38.47Z" }, -] - [[package]] name = "numpy" version = "2.0.2" @@ -3260,7 +3154,6 @@ dev = [ { name = "pytest-env" }, { name = "pytest-randomly" }, { name = "pytest-xdist" }, - { name = "safety" }, { name = "vulture" }, ] @@ -3365,7 +3258,6 @@ dev = [ { name = "pytest-env", specifier = "==1.1.5" }, { name = "pytest-randomly", specifier = "==3.16.0" }, { name = "pytest-xdist", specifier = "==3.6.1" }, - { name = "safety", specifier = "==3.7.0" }, { name = "vulture", specifier = "==2.14" }, ] @@ -4074,15 +3966,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d1/b7/b95708304cd49b7b6f82fdd039f1748b66ec2b21d6a45180910802f1abf1/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:ac37f9f516c51e5753f27dfdef11a88330f04de2d564be3991384b2f3535d02e", size = 562191, upload-time = "2025-11-30T20:24:36.853Z" }, ] -[[package]] -name = "ruamel-yaml" -version = "0.19.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c7/3b/ebda527b56beb90cb7652cb1c7e4f91f48649fbcd8d2eb2fb6e77cd3329b/ruamel_yaml-0.19.1.tar.gz", hash = "sha256:53eb66cd27849eff968ebf8f0bf61f46cdac2da1d1f3576dd4ccee9b25c31993", size = 142709, upload-time = "2026-01-02T16:50:31.84Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b8/0c/51f6841f1d84f404f92463fc2b1ba0da357ca1e3db6b7fbda26956c3b82a/ruamel_yaml-0.19.1-py3-none-any.whl", hash = "sha256:27592957fedf6e0b62f281e96effd28043345e0e66001f97683aa9a40c667c93", size = 118102, upload-time = "2026-01-02T16:50:29.201Z" }, -] - [[package]] name = "s3transfer" version = "0.14.0" @@ -4095,51 +3978,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/48/f0/ae7ca09223a81a1d890b2557186ea015f6e0502e9b8cb8e1813f1d8cfa4e/s3transfer-0.14.0-py3-none-any.whl", hash = "sha256:ea3b790c7077558ed1f02a3072fb3cb992bbbd253392f4b6e9e8976941c7d456", size = 85712, upload-time = "2025-09-09T19:23:30.041Z" }, ] -[[package]] -name = "safety" -version = "3.7.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "authlib" }, - { name = "click" }, - { name = "dparse" }, - { name = "filelock" }, - { name = "httpx" }, - { name = "jinja2" }, - { name = "marshmallow" }, - { name = "nltk" }, - { name = "packaging" }, - { name = "pydantic" }, - { name = "requests" }, - { name = "ruamel-yaml" }, - { name = "safety-schemas" }, - { name = "tenacity" }, - { name = "tomli", marker = "python_full_version < '3.11'" }, - { name = "tomlkit" }, - { name = "typer" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/6f/e8/1cfffa0d8836de8aa31f4fa7fdeb892c7cfa97cd555039ad5df71ce0e968/safety-3.7.0.tar.gz", hash = "sha256:daec15a393cafc32b846b7ef93f9c952a1708863e242341ab5bde2e4beabb54e", size = 330538, upload-time = "2025-11-06T20:10:15.067Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/89/55/c4b2058ca346e58124ba082a3596e30dc1f5793710f8173156c7c2d77048/safety-3.7.0-py3-none-any.whl", hash = "sha256:65e71db45eb832e8840e3456333d44c23927423753d5610596a09e909a66d2bf", size = 312436, upload-time = "2025-11-06T20:10:13.576Z" }, -] - -[[package]] -name = "safety-schemas" -version = "0.0.16" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "dparse" }, - { name = "packaging" }, - { name = "pydantic" }, - { name = "ruamel-yaml" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/c2/ef/0e07dfdb4104c4e42ae9fc6e8a0da7be2d72ac2ee198b32f7500796de8f3/safety_schemas-0.0.16.tar.gz", hash = "sha256:3bb04d11bd4b5cc79f9fa183c658a6a8cf827a9ceec443a5ffa6eed38a50a24e", size = 54815, upload-time = "2025-09-16T14:35:31.973Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/84/a2/7840cc32890ce4b84668d3d9dfe15a48355b683ae3fb627ac97ac5a4265f/safety_schemas-0.0.16-py3-none-any.whl", hash = "sha256:6760515d3fd1e6535b251cd73014bd431d12fe0bfb8b6e8880a9379b5ab7aa44", size = 39292, upload-time = "2025-09-16T14:35:32.84Z" }, -] - [[package]] name = "schema" version = "0.7.5" @@ -4161,15 +3999,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/9d/76/f789f7a86709c6b087c5a2f52f911838cad707cc613162401badc665acfe/setuptools-82.0.1-py3-none-any.whl", hash = "sha256:a59e362652f08dcd477c78bb6e7bd9d80a7995bc73ce773050228a348ce2e5bb", size = 1006223, upload-time = "2026-03-09T12:47:15.026Z" }, ] -[[package]] -name = "shellingham" -version = "1.5.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, -] - [[package]] name = "shodan" version = "1.31.0" @@ -4250,15 +4079,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f", size = 35252, upload-time = "2022-10-06T17:21:44.262Z" }, ] -[[package]] -name = "tenacity" -version = "9.1.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/47/c6/ee486fd809e357697ee8a44d3d69222b344920433d3b6666ccd9b374630c/tenacity-9.1.4.tar.gz", hash = "sha256:adb31d4c263f2bd041081ab33b498309a57c77f9acf2db65aadf0898179cf93a", size = 49413, upload-time = "2026-02-07T10:45:33.841Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d7/c1/eb8f9debc45d3b7918a32ab756658a0904732f75e555402972246b0b8e71/tenacity-9.1.4-py3-none-any.whl", hash = "sha256:6095a360c919085f28c6527de529e76a06ad89b23659fa881ae0649b867a9d55", size = 28926, upload-time = "2026-02-07T10:45:32.24Z" }, -] - [[package]] name = "tldextract" version = "5.3.1" @@ -4310,33 +4130,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/6a/43/8bd850ee71a191bf072e31302c73a66be413fecdd98fdcd111ecbcce13ca/tomlkit-0.15.0-py3-none-any.whl", hash = "sha256:4dbc8f0fc024412b57ced8757ac7461305126a648ff8c2c807fcb8e133a78738", size = 41328, upload-time = "2026-05-10T07:38:23.517Z" }, ] -[[package]] -name = "tqdm" -version = "4.67.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/09/a9/6ba95a270c6f1fbcd8dac228323f2777d886cb206987444e4bce66338dd4/tqdm-4.67.3.tar.gz", hash = "sha256:7d825f03f89244ef73f1d4ce193cb1774a8179fd96f31d7e1dcde62092b960bb", size = 169598, upload-time = "2026-02-03T17:35:53.048Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/16/e1/3079a9ff9b8e11b846c6ac5c8b5bfb7ff225eee721825310c91b3b50304f/tqdm-4.67.3-py3-none-any.whl", hash = "sha256:ee1e4c0e59148062281c49d80b25b67771a127c85fc9676d3be5f243206826bf", size = 78374, upload-time = "2026-02-03T17:35:50.982Z" }, -] - -[[package]] -name = "typer" -version = "0.25.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "annotated-doc" }, - { name = "click" }, - { name = "rich" }, - { name = "shellingham" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/e4/51/9aed62104cea109b820bbd6c14245af756112017d309da813ef107d42e7e/typer-0.25.1.tar.gz", hash = "sha256:9616eb8853a09ffeabab1698952f33c6f29ffdbceb4eaeecf571880e8d7664cc", size = 122276, upload-time = "2026-04-30T19:32:16.964Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3f/f9/2b3ff4e56e5fa7debfaf9eb135d0da96f3e9a1d5b27222223c7296336e5f/typer-0.25.1-py3-none-any.whl", hash = "sha256:75caa44ed46a03fb2dab8808753ffacdbfea88495e74c85a28c5eefcf5f39c89", size = 58409, upload-time = "2026-04-30T19:32:18.271Z" }, -] - [[package]] name = "typing-extensions" version = "4.15.0"