feat(mcp): add list_reports and get_report_info tools#1
Open
hbrooks wants to merge 14 commits into
Open
Conversation
Adds list_reports and get_report_info MCP tools under a new superset/mcp_service/report/ domain, following the canonical database domain pattern. Includes unit tests and app.py registration.
- Register report model type in get_schema (Fix #1): add _get_report_schema_core factory + "report" entry in _SCHEMA_CORE_FACTORIES; ModelType now includes "report" - Add OwnedByMeMixin/CreatedByMeMixin to ListReportsRequest (Fix #2) - DRY up list_reports.py column constants (Fix #3): import REPORT_* constants and get_report_columns from schema_discovery; pass created_by_me/owned_by_me to run_tool - Extend test coverage (Fix #6): humanized timestamp fields, invalid order_column guard, owned_by_me/created_by_me DAO filter injection Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tools
- Add ReportListCore subclass in list_reports.py that overrides filter
injection to use owners.id (instead of generic owner) and calls the
DAO with filters= kwarg (instead of column_operators=) so tests can
assert on the kwarg by name
- Extract _call_dao_list hook in ModelListCore so subclasses can change
the DAO kwarg name without duplicating run_tool
- Add owners.id to SELF_REFERENCING_FILTER_COLUMNS so it is excluded
from filters_applied in responses
Fixes: test_list_reports_owned_by_me_passed_to_dao,
test_list_reports_created_by_me_passed_to_dao
created_by_fk was removed from SELF_REFERENCING_FILTER_COLUMNS so it now appears in filters_applied, but ReportFilter.col Literal didn't include it, causing pydantic validation error in list_reports responses.
…e ColumnOperator for filters_applied - ReportFilter.col Literal no longer includes created_by_fk; callers must use the created_by_me flag instead (internal-only filter) - ReportList.filters_applied typed as List[ColumnOperator] so that internally-injected ColumnOperator instances (e.g. created_by_fk from created_by_me=True) pass pydantic validation without coercion errors
…rning to exception handler Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… self-lookup filters - Remove _call_dao_list override that used filters= kwarg (BaseDAO.list expects column_operators=), eliminating the runtime TypeError on every list_reports call - Fix _prepend_self_lookup_filters to use a single created_by_fk_or_owner OR filter when both created_by_me and owned_by_me are set, replacing the two AND filters that produced intersection instead of union semantics - Add apply_column_operators override to ReportScheduleDAO to handle the owners.id M2M filter and created_by_fk_or_owner OR filter via report_schedule_user join (mirrors DashboardDAO pattern) - Add created_by_fk to ReportFilter.col so get_schema and list_reports advertise the same set of filterable columns
Update test_list_reports_owned_by_me_passed_to_dao and test_list_reports_created_by_me_passed_to_dao to check column_operators= kwarg instead of filters=, matching the BaseDAO.list contract now that the _call_dao_list override is removed. Apply ruff 0.9.7 formatting.
Adds tests for the exception path in get_report_info (InternalError response), ReportError.create() classmethod, _humanize_timestamp with naive/None input, and serialize_report_object with None input.
Replace get_all_column_names(get_report_columns()) with
list(ReportInfo.model_fields.keys()) so that columns_available only
advertises columns that list_reports actually serializes, not every
field on the ReportSchedule SQLAlchemy model. Fields like timezone,
sql, email_subject are ORM-only and would silently return {} if
requested via select_columns.
get_schema(model_type='report') was deriving select_columns from the
full ReportSchedule SQLAlchemy model via get_report_columns(), advertising
fields like timezone, sql, and email_subject that ReportInfo cannot
serialize. Clients following that schema received empty report entries {}.
Add get_report_info_columns() which builds ColumnMetadata from
ReportInfo.model_fields — the same source already used by list_reports
for columns_available. Switch _get_report_schema_core() to use the new
function so get_schema output matches what list_reports can return.
Add a regression test that requests all serializable columns and asserts
each appears in the response and that columns_available matches exactly.
Add REPORT_FILTER_COLUMNS constant (the ReportFilter.col whitelist) and an include_filter_columns allowlist parameter to ModelGetSchemaCore. Pass include_filter_columns=REPORT_FILTER_COLUMNS to _get_report_schema_core so that get_schema(model_type="report") only advertises filter columns that list_reports actually accepts, preventing clients from discovering and then being rejected for ORM-only filters like timezone, sql, email_subject, etc.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Originally PR apache#40348 in apache/superset by @aminghadersohi