Improve Python bindings code quality (Codacy/Bandit cleanup)#4084
Conversation
Not up to standards ⛔🔴 Issues
|
| Category | Results |
|---|---|
| Documentation | 7 minor |
| Security | 1 critical 7 high |
| CodeStyle | 1 minor |
🟢 Metrics 5 complexity
Metric Results Complexity 5
🟢 Coverage ∅ diff coverage · -8.25% coverage variation
Metric Results Coverage variation ✅ -8.25% coverage variation Diff coverage ✅ ∅ diff coverage Coverage variation details
Coverable lines Covered lines Coverage Common ancestor commit (1dc68da) 124062 91858 74.04% Head commit (f365c8c) 155463 (+31401) 102280 (+10422) 65.79% (-8.25%) Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch:
<coverage of head commit> - <coverage of common ancestor commit>Diff coverage details
Coverable lines Covered lines Diff coverage Pull request (#4084) 0 0 ∅ (not applicable) Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified:
<covered lines added or modified>/<coverable lines added or modified> * 100%
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
There was a problem hiding this comment.
Code Review
This pull request implements a comprehensive security hardening of the Python bindings, addressing numerous Bandit findings across the source code, tests, and examples. Key changes include enforcing HTTPS for external data downloads, parameterizing SQL queries to mitigate injection risks, and replacing silent exception suppression with structured logging or narrowed exception handling. The default server host has been updated to localhost for improved security, and a detailed implementation plan for these fixes has been added to the documentation. Feedback suggests extending the host check in server.py to include the IPv6 'all interfaces' address (::) for consistency.
Code Review - PR #4084: Python Bindings Codacy/Bandit CleanupOverall this is a well-structured security cleanup. The changes are logically organized, the Issues1. Plan document should not be committed to the repository
2. uses: actions/setup-python@v5 # floating tagThe existing 3. Breaking change in Changing the default from 4. The same function body is copy-pasted into 5. assert server._config.get("host", "localhost") == "localhost"
6. In {select_statement}
""" # nosec B608Bandit flags the line containing the SQL pattern, not the closing delimiter. The Minor Notes
What's Good
The plan document and unpinned action are the blockers. The rest are improvements but can be addressed in a follow-up if preferred. |
- server.py: drop unused log_swallowed_exception import / _LOGGER (caught by pylint W0611, surfaced via Codacy UnusedCode finding) - server.py: extend host whitelist to IPv6 "::" so Studio URL is rewritten to localhost when bound on either IPv4 or IPv6 all-interfaces address - server.py: document default-host change in ArcadeDBServer.__init__ docstring (no CHANGELOG.md exists in this repo) - test_server.py: drop _config private-state assertion; rely on the publicly-observable get_studio_url() composition instead - test-python-bindings.yml: SHA-pin actions/setup-python to match the rest of the workflow's pinning convention; pin bandit==1.9.4 for reproducible scans
|
Thanks for the review. Walking through each item with verification before implementing: Addressed in b35f8c7Issue 2 - SHA-pin Issue 3 - Document the breaking change: Done. There is no Issue 5 - Test private state: Done. Dropped the Minor (Bandit version): Pinned Codacy Gemini IPv6 suggestion: Applied. Pushing backIssue 1 - Plan doc shouldn't be committed: This repo has an established convention of committing implementation plans to Issue 4 - DRY Issue 6 - Minor "conftest.py:719": That line number doesn't exist - Noted, not addressing this PRMinor (schema.py outer except): Could add a comment justifying the broader CI re-runs against b35f8c7. |
Code Review: Improve Python bindings code quality (Codacy/Bandit cleanup)Overall: This is a well-structured and well-motivated cleanup PR. The changes are genuine improvements: real security fixes in production code, better observability for swallowed exceptions, and a CI gate to prevent regression. The scope is large but the commits are logically organized. A few issues worth discussing before merge. Positives
Issues1.
|
| Category | Status |
|---|---|
| CI gate | Ready |
| Production logging helper | Ready |
| HTTPS enforcement | Ready |
SHA1 usedforsecurity=False |
Ready |
| TEST_PASSWORD centralization | Ready |
docs/superpowers/plans/ file |
Remove before merge |
| Default host breaking change | Needs explicit changelog note or deprecation |
| Narrowed except clauses | Discuss - may be too restrictive |
| IPv6 loopback URL guard | Minor - worth fixing |
| Benchmark nosec without rationale comment | Minor suggestion |
The core of this PR is solid. Removing the planning document and addressing the breaking-change visibility are the two things I would consider blockers.
Code Review - PR #4084: Improve Python bindings code quality (Codacy/Bandit cleanup)Overall this is a well-structured cleanup with clear intent and good commit organization. A few issues worth addressing before merge. OverviewThe PR eliminates 1192 Bandit findings across Issues1. Breaking change - default host silently changed
2. Plan document committed to source tree
3.
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #4084 +/- ##
==========================================
- Coverage 64.94% 64.55% -0.39%
==========================================
Files 1627 1627
Lines 124062 124062
Branches 26454 26454
==========================================
- Hits 80574 80094 -480
- Misses 32234 32823 +589
+ Partials 11254 11145 -109 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Replace try/except/pass (Bandit B110) with log_swallowed_exception so the suppressed error is observable at DEBUG level instead of being silently dropped.
# Python Bindings Codacy/Bandit Cleanup Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Eliminate the Bandit findings Codacy reports against `bindings/python/` (1192 issues across src/tests/examples) by fixing real defects in production code, parameterizing where practical in tests/examples, configuring Bandit to suppress test/example noise that is not actually unsafe, and wiring Bandit into the existing Python CI workflow as a quality gate. **Architecture:** Three-PR rollout. PR1 hardens the production library (`src/`) with no `# nosec` allowed except for documented false positives; adds a project-level Bandit config to `pyproject.toml`; and adds a `bandit` job to `.github/workflows/test-python-bindings.yml`. PR2 sweeps the test suite (move shared test password to `conftest.py`, parameterize SQL where reasonable, suppress idiomatic `assert`/`random` noise via configuration). PR3 sweeps `examples/` (one-character SHA1 fix using `usedforsecurity=False`, narrow targeted suppressions for educational SQL/subprocess usage).
Adds a parallel CI job that fails the build on any Bandit finding in the production source tree. Also fixes the exclude_dirs glob anchors in [tool.bandit] config so substring matches like 'build' don't accidentally exclude examples/11_vector_index_build.py.
Broadens the existing CI Bandit gate to scan tests/ alongside src/. Also fixes the [tool.bandit] config: bandit's pyproject.toml support doesn't honor [tool.bandit.assert_used].skips, so we use the global skips = ["B101"] form instead. B101 is the standard pytest idiom and src/ intentionally contains no asserts.
- server.py: drop unused log_swallowed_exception import / _LOGGER (caught by pylint W0611, surfaced via Codacy UnusedCode finding) - server.py: extend host whitelist to IPv6 "::" so Studio URL is rewritten to localhost when bound on either IPv4 or IPv6 all-interfaces address - server.py: document default-host change in ArcadeDBServer.__init__ docstring (no CHANGELOG.md exists in this repo) - test_server.py: drop _config private-state assertion; rely on the publicly-observable get_studio_url() composition instead - test-python-bindings.yml: SHA-pin actions/setup-python to match the rest of the workflow's pinning convention; pin bandit==1.9.4 for reproducible scans
The Python wrapper's _convert_args path only handles a single positional
? parameter (numpy/list rebinding); a multi-? command("sql", sql, i, vec)
dispatches to JPype as command(str, str, int, list) which has no Java
overload. Revert to embedded-literal SQL with # nosec B608 (annotated
with the rationale inline). DELETE keeps its single-param parameterization
since that is supported. Caught by test_vector_delete_and_search_others_sql
in CI.
4c28a1c to
f365c8c
Compare
Code Review - PR #4084: Improve Python Bindings Code Quality (Codacy/Bandit Cleanup)Summary: This PR cleans up Bandit security findings in Strengths
IssuesBreaking Change - Server Default Host (high impact)
Changing the default The docstring mentions "Earlier versions defaulted to
Plan Document Should Not Be in the Repo
This 1457-line file is an internal agentic implementation plan - it contains instructions like Version Drift Between CI and
|
(cherry picked from commit 0efd60a)
Summary
Eliminates the Codacy/Bandit findings in
bindings/python/and adds a CI gate to prevent regression. Plan documented atdocs/superpowers/plans/2026-05-05-python-bindings-codacy-fixes.md.Bandit posture before vs. after:
src/tests/examples/What changed
src/): New_logginghelper module replaces silenttry/except/passswallowing with debug-level traceback logging acrossasync_executor,graph_batch,core(__del__),jvm(shutdown_jvm),schema, andserver. Finalizers narrowed from bareexcept Exceptionto(AttributeError, RuntimeError).ArcadeDBServerdefault host changed from0.0.0.0tolocalhost(callers must opt in to bind on all interfaces). One annotated false-positive invector.pywhere the SQL identifiers are quoted via_quote_identifier()and the user key is passed as a?parameter.tests/):TEST_PASSWORDconstant centralised inconftest.py. Vector INSERT/DELETE intest_vector_sql.pynow parameterized with?. Bench-loop SQL intest_server_patterns.pyannotated (parameterizing would change the workload being measured). Idiomaticassertstatements skipped via[tool.bandit] skips = ["B101"].examples/): SHA1 short-digests now useusedforsecurity=False. URL fetches indownload_data.pyand21_server_mode_http_access.pyare HTTPS-validated via a_require_https()guard. SQL string-builds in numbered demos either parameterized (17_timeseries_end_to_end.py) or annotated where interpolated values are script constants.banditjob in.github/workflows/test-python-bindings.ymlruns in parallel with the existing test matrix. Two gates:src+tests: must be clean at low-severity / low-confidence.examples: must be clean at medium-severity / high-confidence.In-flight discoveries
exclude_dirs = ["build", ...]in bandit's pyproject config was substring-matchingexamples/11_vector_index_build.py. Fixed by anchoring patterns with/.[tool.bandit.assert_used] skipsfrom pyproject.toml; switched to globalskips = ["B101"]. Safe becausesrc/has noassertstatements.Test plan
banditjob passes on Linux runnertestmatrix continues to pass on linux/amd64, linux/arm64, darwin/arm64, windows/amd64 across Python 3.10-3.14Server.__del__still tears down cleanly when JVM is already detached (covered by existing teardown tests)ArcadeDBServer(root_password=...)defaults to localhost; explicithost="0.0.0.0"still works for opt-in (covered by newtest_default_host_is_localhost)python3 -m bandit -c bindings/python/pyproject.toml -r bindings/python/src bindings/python/tests --severity-level low --confidence-level lowexits 0python3 -m bandit -c bindings/python/pyproject.toml -r bindings/python/examples --severity-level medium --confidence-level highexits 0Reviewing
The 21 commits map 1:1 to plan tasks and group naturally into 3 logical phases at boundaries
27da10759(end of src+CI),c8121a024(end of tests), andfdfda61cd(end of examples). Reviewers can read the commits in order and stop at any boundary.