Skip to content

feat: add read-only discovery and admin tools (9 tools) - #178

Open
Avicennasis wants to merge 10 commits into
googleanalytics:mainfrom
Avicennasis:feat/read-only-tools
Open

feat: add read-only discovery and admin tools (9 tools)#178
Avicennasis wants to merge 10 commits into
googleanalytics:mainfrom
Avicennasis:feat/read-only-tools

Conversation

@Avicennasis

Copy link
Copy Markdown

Summary

Adds nine read-only tools that close common discovery gaps when an LLM works with a GA4 property. All tools follow the existing patterns in tools/admin/info.py and tools/reporting/metadata.py, use the already-wired client factories from tools/client.py, and fit the existing analytics.readonly scope (verified per method against the API reference).

One commit per tool for easy review:

Tool API Why
list_key_events Admin v1beta properties.keyEvents.list Discover what a property counts as conversions
list_data_streams Admin v1beta properties.dataStreams.list Platforms + measurement IDs feeding the property
get_metadata Data v1beta properties.getMetadata Full dimension/metric catalog (existing get_custom_dimensions_and_metrics is unchanged and still returns the custom-only subset)
list_properties Admin v1beta properties.list Full property objects under an account; complements get_account_summaries
list_custom_dimensions / list_custom_metrics Admin v1beta Scope, parameter names, descriptions the Data API metadata doesn't return
run_access_report Admin v1beta runAccessReport Data-access auditing at property or account level
get_data_retention_settings Admin v1beta Compliance + explains missing older data
list_audiences Admin v1alpha properties.audiences.list Audience discovery (same alpha channel as list_property_annotations)
get_property_quotas Data v1alpha getPropertyQuotasSnapshot Pre-flight quota check before expensive report batches

Also adds a construct_account_rn helper to utils.py, mirroring construct_property_rn, for the account-scoped tools.

Testing

  • Unit tests for every tool (request construction, response conversion, invalid-ID validation): tests/info_test.py, tests/metadata_test.py, tests/access_test.py, tests/quotas_test.py, plus construct_account_rn coverage in tests/utils_test.py
  • nox -s lint (black -l 80) clean; full unittest suite passes (31 tests)

Happy to split this into smaller PRs if preferred — each commit stands alone.

Lists the key events (conversions) configured for a GA4 property via
the Admin API properties.keyEvents.list method. Read-only; fits the
existing analytics.readonly scope.
Lists the data streams (web, Android, iOS) configured for a GA4
property via the Admin API properties.dataStreams.list method,
including platform-specific details such as web measurement IDs.
Read-only; fits the existing analytics.readonly scope.
Exposes the complete properties.getMetadata response — standard and
custom dimensions and metrics with descriptions, categories, and
deprecation status — so an LLM can discover available fields before
building a report. The existing get_custom_dimensions_and_metrics
tool is unchanged and still returns only custom definitions.
Lists the GA4 properties under an account via the Admin API
properties.list method with a parent account filter. Returns full
property objects (display name, industry, time zone, currency,
service level), complementing the summary info available from
get_account_summaries. Adds a construct_account_rn helper to utils
mirroring construct_property_rn.
Lists custom dimensions and metrics via the Admin API, which returns
richer detail than the Data API metadata endpoint: scope, parameter
name, description, measurement unit, and ads personalization /
restricted metric flags. Read-only; fits the existing
analytics.readonly scope.
Runs a data access report via the Admin API runAccessReport method,
showing who accessed Analytics data, when, and how. Supports both
property-level and account-level entities. Read-only; the method
accepts the analytics.readonly scope.
Retrieves a property's data retention settings via the Admin API,
showing how long event-level and user-level data is kept. Helps
answer compliance questions and explains why older data may be
missing from reports. Read-only; fits the existing
analytics.readonly scope.
Lists the audiences defined on a GA4 property via the Admin API
alpha channel, following the same pattern as the existing
list_property_annotations tool. Read-only; fits the existing
analytics.readonly scope.
Retrieves the current Data API quota snapshot for a property via the
alpha getPropertyQuotasSnapshot method, so callers can check token
consumption before running expensive batches and back off
intelligently. Read-only; fits the existing analytics.readonly
scope.
get_metadata and get_custom_dimensions_and_metrics both built the client
in the same expression that validated the property ID:

    create_data_api_client().get_metadata(
        name=f"{construct_property_rn(property_id)}/metadata"
    )

Python evaluates create_data_api_client() first, so on any machine without
Application Default Credentials an invalid property ID surfaced as
google.auth.exceptions.DefaultCredentialsError instead of the ValueError
the docstring promises — which is what failed
metadata_test.TestGetMetadata.test_invalid_property_id_raises in CI.

Hoisting the resource-name construction validates the input before any
credential lookup. Verified by running the suite with ADC disabled
(CLOUDSDK_CONFIG pointed at an empty dir): the test fails with
DefaultCredentialsError before this change and passes after, 31/31 green.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant