gads v3.8.2 — analyze suite, agent-driveable, latest-of-all, graceful errors#1
Merged
Conversation
New 'analyze' command group with five read-only analyses (no account mutations): - analyze landing-page : score branch LP for conversion readiness - analyze wasted-spend : AED-ranked zero/low-conversion search terms & campaigns - analyze ngrams : 1/2/3-gram search-term clustering (Arabic + English) - analyze ad-copy : performance-ranked RSA ads + PARTS-ONLY rule validation - analyze competition : impression-share pressure + best-effort auction insights Adds gads_lib/analyze/ sub-package. Bumps version 3.3.0 -> 3.4.0.
Add CLI-native gaps so an LLM can drive gads without an MCP server:
- catalog: machine-readable manifest of all commands/params/help by
walking the live Click tree (gads catalog --json)
- structured error envelope + stable exit codes (0-7) emitted to stderr
as {"error":{...}} when --json is in effect; print_error/EXIT_CODES
helpers in output.py
- read-only history-DB access: gads db "<SELECT>" (SELECT-only, mutations
rejected, PRAGMA query_only) + gads changelog/decisions/milestones
- --json on log, snapshot, refresh; global --plain/--quiet flags
- AGENTS.md + llms.txt capability index
New modules: gads_lib/catalog.py, gads_lib/dbread.py
Google Ads:
- Default API version v19 -> v24 (v19 sunset 2026-02-11; v24 is current GA).
GAQL search/searchStream, mutate, uploadClickConversions unchanged.
- Rebuild keyword forecast body for v24 generateKeywordForecastMetrics
(campaign/adGroups[].keywords[{text,matchType}], manualCpc biddingStrategy,
required forecastPeriod YYYY-MM-DD). Verified live: returns real forecast.
- Fix generateKeywordIdeas payload to documented schema (language string,
geoTargetConstants string array, keywordPlanNetwork, keywordAndUrlSeed).
Verified live: returns ideas.
- keyword ideas/forecast accept ISO codes (en/ar, AE) or numeric constant IDs;
IDs verified via live language_constant / geo_target_constant queries.
Merchant Center:
- Migrate from Content API for Shopping v2.1 (sunsets 2026-08-18) to
Merchant API v1 (merchantapi.googleapis.com); scope unchanged (auth/content).
Command names + table output preserved; --json now returns v1 shapes.
- Update cli.py merchant renderers for new v1 response fields.
Dependencies/security:
- Raise floors: requests>=2.33.0 (CVE-2024-47081, CVE-2026-25645),
python-dotenv>=1.2.2 (CVE-2026-28684), click>=8.1, google-auth>=2.35,
google-auth-oauthlib>=1.2; dev pytest>=9.0, pytest-cov>=6.0 (<7 keeps
subprocess coverage).
Docs (CLAUDE.md/README/.env.example) and CHANGELOG updated.
…itemaps, GBP local-posts, KB drift check
…ift fix, tests A) KB expansion (task #14): all 5 API KB files now include comprehensive Developer Guide sections (schemas, enums, workflows, limits, best practices). Total KB: 5,793 → 10,764 lines. google-ads.md +1,406 | merchant-api.md +1,037 | ga4.md +873 | gbp.md +1,099 | search-console.md +551. INDEX.md updated. B) GSC OAuth scope fix (task #18): add webmasters.readonly to generate_token.py SCOPES list. Root cause of GSC 403 errors. User must re-run generate_token.py. C) GA4 Admin v1alpha→v1beta migration: GA4_ADMIN_BASE in ga4.py migrated to v1beta (stable, "no breaking changes" guarantee). gads kb check now exits 0. D) Code↔KB cross-references (task #15): 44 KB reference comments added across ads.py, ga4.py, gbp.py, gsc.py, merchant.py (module docstrings + per-function # KB: annotations pointing to kb/<slug>.md and official doc URLs). D) Test suite (task #16): tests/test_gads.py — 58 tests, all pass, fully offline (mocked HTTP). Covers request shapes, --json output, SELECT guard, error envelope, kb check alignment, manifest validity, version sentinel. E) Graceful access-error handling: output.py gains classify_api_error() + offer_gcloud_enable(); http.py dispatches 4 error classes (API_NOT_ENABLED with interactive gcloud enable offer, MERCHANT_NOT_REGISTERED, INSUFFICIENT_SCOPE naming the missing scope, PERMISSION_DENIED/allowlist). Exit code 5, no tracebacks. 7 new tests in TestGracefulErrorHandling cover all 4 mappings + gcloud absent/present.
…ss errors in --json mode
When --json is active, API access errors (API_NOT_ENABLED, MERCHANT_NOT_REGISTERED,
INSUFFICIENT_SCOPE, PERMISSION_DENIED) now write {"error": {...}} to STDOUT and exit 5,
instead of printing human advisory text to STDERR with empty STDOUT.
- http.py: request_json() accepts as_json=False; classified errors branch on it
- merchant.py, gsc.py, ga4.py, gbp.py: thread as_json through all request_json callers
- cli.py: pass as_json=as_json at every affected call site
- Interactive gcloud-enable offer suppressed in JSON mode (action/url in envelope instead)
- Non-JSON mode: all existing colorized advisory output preserved unchanged
- Exit code 5 preserved in all paths
- tests: 6 new tests (TestJsonModeAccessErrors) covering all 4 error classes + non-JSON regression
- bump gads_lib.__version__ to 3.8.1
…27 tests, KB drift fix
Closes all 5 items from the v3.8.2 hardening audit:
1. Error routing (MODERATE): All raw requests call-sites in ads.py
(run_gaql, ads_search, ads_mutate, ads_batch_mutate,
ads_upload_click_conversions, generate_keyword_ideas,
generate_keyword_forecast, audience_upload_csv job/run steps),
ga4.py (list_key_events, create_key_event, delete_key_event via new
_handle_admin_error helper), and gbp.py (gbp_multi_daily_metrics)
now route through request_json(). Under --json a 4xx emits a
classified JSON envelope {"error":{code,message,action,...}} to
stdout and exits 5. Human mode preserves GA4-specific scope hints.
2. partialFailure (MODERATE): conversion_upload_cmd now checks
result.get("partialFailureError") on HTTP 200. If present: human
mode warns + prints per-conversion field path/error; --json mode
returns structured {"status":"partial_failure",...}; exits 1.
No longer silently prints "✓ Conversion uploaded" on partial failure.
3. Tests: 64 → 127 offline mocked tests. New tests cover every
endpoint in ads.py / ga4.py / gbp.py / gsc.py / merchant.py:
request-construction correctness (URL/body/params) + error-envelope
behaviour under as_json=True.
4. KB drift: search-console.md L445 "CLI gap" → "Implemented";
coverage table sitemaps.*/"URL Inspection API" rows updated to Yes;
coverage-gaps list items 4+5 removed. INDEX.md updated.
5. Env deps: requests 2.32.3→2.34.2 (floor >=2.33.0),
python-dotenv 1.0.1→1.2.2 (floor >=1.2.2). All 127 tests green.
- README.md: command count 75→108, add Analyze/KB groups, update GBP (16 cmds) and GSC (6 cmds) rows, update architecture tree (gsc.py, catalog.py, dbread.py, analyze/, kb/, tests/), fix Merchant API v1 enable link - CLAUDE.md: add analyze group, kb group, missing top-level cmds (catalog/db/changelog/decisions/milestones), update GBP/GSC command lists, expand Architecture, add analyze/kb/gsc usage examples - llms.txt: fix API version v23→v24 - RELEASE_NOTES.md: new file summarising v3.4.0→v3.8.2 for GitHub release
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.
Summary
analyze landing-page,wasted-spend,ngrams,ad-copy,competition. Zero account mutations.gads catalog --json(live Click-tree manifest), history-DB passthrough (db/changelog/decisions/milestones), structured error envelopes with stable exit codes (0–7), global--plain/--quiet,AGENTS.md+llms.txtat CLI root.Known pending
Test plan