Skip to content

fix(mcp): honor use_cache and cache_timeout in get_chart_data - #43349

Open
justinpark wants to merge 2 commits into
apache:masterfrom
justinpark:fix/mcp-get-chart-data-cache-control
Open

fix(mcp): honor use_cache and cache_timeout in get_chart_data#43349
justinpark wants to merge 2 commits into
apache:masterfrom
justinpark:fix/mcp-get-chart-data-cache-control

Conversation

@justinpark

Copy link
Copy Markdown
Member

SUMMARY

get_chart_data's docstring advertises Cache control: use_cache, force_refresh, cache_timeout, but only force_refresh was actually wired into the QueryContext's force flag:

  • use_cache=False was silently ignored — the tool would still read from cache even when a caller explicitly asked it not to.
  • cache_timeout was never applied anywhere, despite being a documented, logged request field.

This fixes both by:

  • Computing effective_force = force_refresh or not use_cache once per call path, and using it everywhere the tool builds or patches a QueryContext (the cached-form_data path, the no-saved-query_context fallback path, the saved-query_context patch path, and the unsaved-chart-only _query_from_form_data path), instead of force=request.force_refresh.
  • Threading cache_timeout through as QueryContextFactory's existing custom_cache_timeout parameter (already supported by QueryContext/QueryContextFactory and by ChartDataQueryContextSchema as a top-level field) — added as a new optional param on build_query_context_from_form_data in chart_helpers.py and passed through at every call site.

No behavior changes for existing callers that don't set use_cache/cache_timeout: defaults are use_cache=True, cache_timeout=None, so effective_force reduces to force_refresh as before.

TESTING INSTRUCTIONS

  • Added test_query_from_form_data_use_cache_false_bypasses_cache (parametrized over use_cache/force_refresh combinations) to tests/unit_tests/mcp_service/chart/tool/test_get_chart_data.py, asserting the force and custom_cache_timeout kwargs passed to build_query_context_from_form_data.
  • ruff check / ruff format --check / python -m py_compile pass on all changed files.
  • Could not run the full unit test suite in this environment due to a pre-existing, unrelated local SQLAlchemy/Flask-AppBuilder init issue (Connection.rollback() missing) that reproduces identically on master before this change.

ADDITIONAL INFORMATION

  • Has associated issue:
  • Required feature flags:
  • Changes UI
  • Includes DB Migration
  • Introduces new feature or API
  • Removes existing feature or API

get_chart_data's docstring advertises "Cache control: use_cache,
force_refresh, cache_timeout", but only force_refresh was ever wired
into the QueryContext's force flag. use_cache=False was silently
ignored (the tool would still read cache), and cache_timeout was
never applied at all.

Compute an effective_force = force_refresh or not use_cache and use
it everywhere the tool builds/patches a QueryContext, and thread
cache_timeout through as QueryContextFactory's existing
custom_cache_timeout parameter (also exposed as a top-level field on
the saved query_context JSON via ChartDataQueryContextSchema).
@dosubot dosubot Bot added the infra:caching Infra setup and configuration related to caching label Aug 19, 2026
@bito-code-review

bito-code-review Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #8099d9

Actionable Suggestions - 0
Review Details
  • Files reviewed - 3 · Commit Range: 2e3e651..2e3e651
    • superset/mcp_service/chart/chart_helpers.py
    • superset/mcp_service/chart/tool/get_chart_data.py
    • tests/unit_tests/mcp_service/chart/tool/test_get_chart_data.py
  • Files skipped - 0
  • Tools
    • MyPy (Static Code Analysis) - ✔︎ Successful
    • Astral Ruff (Static Code Analysis) - ✔︎ Successful
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

Comment on lines 1128 to 1130
cache_status = get_cache_status_from_result(
query_result, force_refresh=request.force_refresh
query_result, force_refresh=effective_force
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: The refreshed response field is documented and implemented as indicating a force refresh, but passing effective_force makes every use_cache=False, force_refresh=False request report refreshed=True. This conflates cache bypassing with an explicit refresh and produces an incorrect cache status for callers; pass the original request.force_refresh when constructing response metadata while retaining effective_force for query execution. [cache]

Severity Level: Minor 🧹
- ⚠️ `ChartData.cache_status.refreshed` misrepresents cache-bypass requests.
- ⚠️ MCP clients cannot distinguish bypassing cache from explicit refresh.
- ⚠️ Saved and unsaved chart responses expose inconsistent request semantics.

Use CodeAnt Skill

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** superset/mcp_service/chart/tool/get_chart_data.py
**Line:** 1128:1130
**Comment:**
	*Cache: The `refreshed` response field is documented and implemented as indicating a force refresh, but passing `effective_force` makes every `use_cache=False, force_refresh=False` request report `refreshed=True`. This conflates cache bypassing with an explicit refresh and produces an incorrect cache status for callers; pass the original `request.force_refresh` when constructing response metadata while retaining `effective_force` for query execution.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

@bito-code-review

Copy link
Copy Markdown
Contributor

The flagged issue is correct. Using effective_force (which includes not request.use_cache) to populate the refreshed field in cache_status incorrectly signals an explicit refresh even when the user only intended to bypass the cache. To resolve this, you should pass request.force_refresh directly to get_cache_status_from_result while continuing to use effective_force for the actual query execution.

Would you like me to fetch all other comments on this PR to validate and implement fixes for them as well?

superset/mcp_service/chart/tool/get_chart_data.py

# Cache status information using utility function
            cache_status = get_cache_status_from_result(
                query_result, force_refresh=request.force_refresh
            )

@codecov

codecov Bot commented Aug 19, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 66.73%. Comparing base (faf7c34) to head (3d208df).
⚠️ Report is 2 commits behind head on master.

Files with missing lines Patch % Lines
superset/mcp_service/chart/tool/get_chart_data.py 0.00% 5 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##           master   #43349   +/-   ##
=======================================
  Coverage   66.73%   66.73%           
=======================================
  Files        2876     2876           
  Lines      164201   164205    +4     
  Branches    37887    37888    +1     
=======================================
+ Hits       109577   109580    +3     
- Misses      52467    52469    +2     
+ Partials     2157     2156    -1     
Flag Coverage Δ
hive 38.10% <0.00%> (-0.01%) ⬇️
mysql 57.76% <0.00%> (-0.01%) ⬇️
postgres 57.79% <0.00%> (+<0.01%) ⬆️
presto 40.04% <0.00%> (-0.01%) ⬇️
python 59.18% <0.00%> (+<0.01%) ⬆️
sqlite 57.43% <0.00%> (-0.01%) ⬇️
unit 100.00% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

…ed field

get_chart_data used effective_force (which also folds in use_cache=False)
when building the refreshed cache_status field, so any use_cache=False
request incorrectly reported refreshed=True. effective_force is still
used for actual query execution to bypass the cache.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@bito-code-review

bito-code-review Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #331fa3

Actionable Suggestions - 0
Review Details
  • Files reviewed - 1 · Commit Range: 2e3e651..3d208df
    • superset/mcp_service/chart/tool/get_chart_data.py
  • Files skipped - 0
  • Tools
    • MyPy (Static Code Analysis) - ✔︎ Successful
    • Astral Ruff (Static Code Analysis) - ✔︎ Successful
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

infra:caching Infra setup and configuration related to caching size/M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant