Skip to content

searchstack gsc: missing query() function + missing first-run OAuth bootstrap #5

Description

@AO-Raffa

Two related bugs prevent searchstack gsc from working on a fresh install. Both reproduce on main (current head) installed via pipx install git+https://github.com/alexpospekhov/searchstack-aeo.git@main. Companion to #4 (which covered the geo command).

Bug 1 — providers.gsc.query doesn't exist

commands/gsc_cmd.py calls gsc.query(...) in 5 places (lines 59, 104, 152, 192, 233), but providers/gsc.py only defines get_gsc_token, gsc_request, get_gsc_site_url_encoded. No query function.

Result: every searchstack gsc, searchstack gsc pages-perf, searchstack gsc devices, searchstack gsc countries, searchstack gsc trend errors with:

Error fetching GSC data: module 'searchstack.providers.gsc' has no attribute 'query'

Other commands (monitor.py, audit.py, report.py, pages.py) correctly use gsc_request directly with a constructed endpoint — that's the working pattern.

Bug 2 — get_gsc_token has no first-run OAuth bootstrap

The README claims:

This opens your browser. Sign in with the Google account that has Search Console access. Grant permissions. A token.pickle file is saved automatically.

But providers/gsc.py:20–48 only loads + refreshes an existing token.pickle. There's no InstalledAppFlow.from_client_secrets_file(...).run_local_server() call anywhere in the codebase. Searching for InstalledAppFlow, run_local_server, pickle.dump only finds the refresh-write path inside get_gsc_token, never the initial create.

Result on a clean install: even after Bug 1 is fixed, gsc_request always returns None because get_gsc_token returns None for a missing token.pickle. README promise is unfulfilled.

Repro on a clean machine

pipx install git+https://github.com/alexpospekhov/searchstack-aeo.git@main
# Configure .searchstack.toml with valid [gsc] credentials_file + site_url
searchstack gsc
# → Top Queries header prints, then AttributeError
# Even after patching Bug 1: → "GSC authentication failed" because no token.pickle exists and nothing creates it

Suggested fixes

Bug 1: add query() to providers/gsc.py

def query(
    site_url: str,
    start_date: str,
    end_date: str,
    dimensions: list[str],
    config: Config,
    row_limit: int = 1000,
) -> dict[str, Any]:
    """Query the GSC Search Analytics endpoint."""
    encoded_site = quote(site_url, safe="")
    endpoint = f"webmasters/v3/sites/{encoded_site}/searchAnalytics/query"
    body = {
        "startDate": start_date,
        "endDate": end_date,
        "dimensions": dimensions,
        "rowLimit": row_limit,
    }
    data = gsc_request(config, endpoint, method="POST", body=body)
    if data is None:
        raise RuntimeError("GSC authentication failed. token.pickle missing or invalid.")
    if isinstance(data, dict) and "error" in data:
        raise RuntimeError(data["error"])
    return data

Bug 2: add OAuth bootstrap to get_gsc_token

Prepend a missing-token branch that runs InstalledAppFlow:

if not token_path.exists():
    if not creds_path.exists():
        print(f"✗ GSC credentials file not found: {creds_path}")
        return None
    try:
        from google_auth_oauthlib.flow import InstalledAppFlow
    except ImportError:
        print("✗ google-auth-oauthlib not installed.")
        return None
    SCOPES = [
        "https://www.googleapis.com/auth/webmasters.readonly",
        "https://www.googleapis.com/auth/webmasters",
        "https://www.googleapis.com/auth/indexing",
    ]
    print(f"  No token.pickle. Starting OAuth flow. Sign in with the GSC-owning account.")
    flow = InstalledAppFlow.from_client_secrets_file(str(creds_path), SCOPES)
    new_creds = flow.run_local_server(port=0)
    with open(token_path, "wb") as f:
        pickle.dump(new_creds, f)
    token_path.chmod(0o600)
    return new_creds.token

google-auth-oauthlib is already in your declared dependencies (pyproject.toml).

Verified result

With both fixes applied locally, searchstack gsc on an allowed.online property returns real data:

Google Search Console -- Top Queries
Period: 2026-04-26 to 2026-05-24

  No token.pickle found. Starting first-run OAuth flow.
  [browser opens, user signs in + grants 3 scopes]
  ✓ token.pickle saved to ./token.pickle

    #  Query             Clicks   Impr     CTR   Pos
  ---  ----------------  -------  -----  ------  -----
    1  allow                  0      5    0.0%   56.2
    2  allow online           0      1    0.0%   38.0
    3  allowed                0      6    0.0%   46.3

  3 queries shown.

Happy to open a PR. Tagged alongside #4 for context.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions