{"id":30593369,"url":"https://github.com/techwithty/google-search-console-sdk","last_synced_at":"2025-08-29T18:13:41.660Z","repository":{"id":309600298,"uuid":"1036893094","full_name":"TechWithTy/google-search-console-sdk","owner":"TechWithTy","description":"Google Search Console SDK for Python: OAuth2 client, typed models, utilities, and quickstart scripts.","archived":false,"fork":false,"pushed_at":"2025-08-12T19:13:39.000Z","size":15,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-08-12T20:30:22.311Z","etag":null,"topics":["analytics","google-search-console","oauth2","python","sdk","search-console","seo","server-side","webmasters"],"latest_commit_sha":null,"homepage":"https://www.cybershoptech.com","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/TechWithTy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-08-12T18:33:03.000Z","updated_at":"2025-08-12T19:13:42.000Z","dependencies_parsed_at":"2025-08-12T20:30:28.037Z","dependency_job_id":null,"html_url":"https://github.com/TechWithTy/google-search-console-sdk","commit_stats":null,"previous_names":["techwithty/google-search-console-sdk"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/TechWithTy/google-search-console-sdk","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TechWithTy%2Fgoogle-search-console-sdk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TechWithTy%2Fgoogle-search-console-sdk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TechWithTy%2Fgoogle-search-console-sdk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TechWithTy%2Fgoogle-search-console-sdk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TechWithTy","download_url":"https://codeload.github.com/TechWithTy/google-search-console-sdk/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TechWithTy%2Fgoogle-search-console-sdk/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272735314,"owners_count":24984283,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-29T02:00:10.610Z","response_time":87,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["analytics","google-search-console","oauth2","python","sdk","search-console","seo","server-side","webmasters"],"created_at":"2025-08-29T18:13:41.047Z","updated_at":"2025-08-29T18:13:41.651Z","avatar_url":"https://github.com/TechWithTy.png","language":"Python","readme":"# CyberOni Google Search Console SDK (Python)\n\nUtilities and a lightweight client for the Google Search Console (Webmasters v3) API. Includes typed models, retrying HTTP logic, and quickstart scripts for both installed-app (interactive) and service-account (server) authentication.\n\n- Folder: `backend/app/core/landing_page/google_search_console/`\n- Main client: `client.py` exposing `GSCClient`\n- Models: `api/_requests.py`, `api/_responses.py`\n- Helpers: `api/sitemaps.py` utilities\n- Scripts: `scripts/quickstart_gsc.py`, `scripts/quickstart_gsc_service_account.py`\n\n## Features\n- OAuth2 authentication (installed app or service account)\n- Search Analytics query with typed request/response models\n- Sites and Sitemaps helpers (`sites_list`, `sites_add`, `sites_get`, `sitemaps_*`)\n- Robust HTTP error handling with retries/backoff\n\n## Requirements\n- Python 3.10+\n- Enabled API in your Google Cloud project: `webmasters.googleapis.com` (Search Console API)\n- Search Console access to the property (your user or your service account must be a user/owner)\n\n## Installation\n\nUsing `uv` in this subfolder (recommended):\n```bash\n# from: backend/app/core/landing_page/google_search_console/\nuv pip install -e .\n```\n\nOr with pip:\n```bash\n# from: backend/app/core/landing_page/google_search_console/\npip install -e .\n```\n\nDependencies are defined in `pyproject.toml`:\n- `requests`, `google-auth`, `google-auth-oauthlib`, `pydantic`, `pytest` (dev)\n\n## Environment variables\nCopy `.env.example` and fill real values (Windows paths are fine):\n\n```dotenv\n# Installed-app OAuth (optional for local interactive)\nGSC_CLIENT_SECRETS=C:\\secrets\\gsc\\client_secrets.json\nGSC_TOKEN_PATH=./.gsc_token.json\n\n# Service Account (server/CI)\nGSC_SA_KEY=C:\\secrets\\gsc\\analytics-deal-scale.json\nGSC_SCOPE=https://www.googleapis.com/auth/webmasters.readonly\n\n# Property identifier (must match property type EXACTLY)\n# URL-prefix example (note trailing slash): https://dealscale.io/\n# Domain property example: sc-domain:dealscale.io\nGSC_SITE_URL=https://dealscale.io/\n\n# Optional HTTP tweaks\nGSC_HTTP_TIMEOUT=30\nGSC_USER_AGENT=DealScale-GSC-SDK/1.0\n```\n\nHow to determine `GSC_SITE_URL`:\n- If your property type in Search Console is URL-prefix, use the full URL with scheme and trailing slash, e.g. `https://dealscale.io/`.\n- If it is a Domain property, use `sc-domain:dealscale.io`.\n- You can also run `client.sites_list()` and copy the `siteUrl` value shown.\n\n## Authentication options\n\n### A) Installed-app OAuth (interactive; easiest for local)\n1) In Google Cloud Console: configure OAuth consent screen, create an OAuth Client of type \"Desktop app\" and download its JSON.\n2) Set `GSC_CLIENT_SECRETS` (and optionally `GSC_TOKEN_PATH`).\n3) Run the quickstart:\n```bash\n# from repo root, module path assumes CWD is backend/\npython -m app.core.landing_page.google_search_console.scripts.quickstart_gsc\n```\n- First run opens a browser for sign-in; token is cached. Subsequent runs are silent.\n\n### B) Service account (server/CI; headless)\n1) Create a Service Account and JSON key in your Google Cloud project.\n2) In Search Console UI for your property, add the SA email as a user (Settings → Users and permissions → Add user).\n3) Ensure API `webmasters.googleapis.com` is enabled in the same project.\n4) Set env vars and run the quickstart:\n```bash\n# PowerShell example (Windows)\n$env:GSC_SA_KEY=\"C:\\secrets\\gsc\\analytics-deal-scale.json\"\n$env:GSC_SITE_URL=\"https://dealscale.io/\"   # or sc-domain:dealscale.io\n$env:GSC_SCOPE=\"https://www.googleapis.com/auth/webmasters.readonly\"\n\n# from repo root, set CWD to backend so app.* resolves\npython -m app.core.landing_page.google_search_console.scripts.quickstart_gsc_service_account\n```\nWhat the script does:\n- Exchanges SA key for an access token.\n- Registers the site for the SA (`client.sites_add()`), then verifies (`client.sites_get()`).\n- Runs a short Search Analytics query and prints rows.\n\n## Programmatic usage examples\n\n```python\nfrom backend.app.core.landing_page.google_search_console import GSCClient, SearchAnalyticsQueryRequest\n\n# If you already have an OAuth access token (e.g., service account):\nclient = GSCClient(access_token=\"\u003cACCESS_TOKEN\u003e\")\n\n# List sites\nprint(client.sites_list())\n\n# Query Search Analytics\nreq = SearchAnalyticsQueryRequest(\n    startDate=\"2025-07-01\",\n    endDate=\"2025-07-31\",\n    dimensions=[\"QUERY\", \"PAGE\"],\n    rowLimit=50,\n)\nresp = client.search_analytics_query(\"https://dealscale.io/\", req)\nprint(len(resp.rows), \"rows\")\n\n# Sitemaps\nprint(client.sitemaps_list(\"https://dealscale.io/\"))\nclient.sitemaps_submit(\"https://dealscale.io/\", \"sitemap.xml\")\nclient.sitemaps_delete(\"https://dealscale.io/\", \"sitemap.xml\")\n```\n\n## Troubleshooting\n- **401 Unauthorized**\n  - Token expired/invalid; re-auth.\n  - Service account not added as a user on the property.\n- **403 Forbidden: insufficient permissions**\n  - The identity (user or SA) lacks permission on the property. Add it in Search Console Settings.\n- **Site URL mismatch**\n  - `GSC_SITE_URL` must match the property type exactly. URL-prefix requires scheme and trailing slash; domain uses `sc-domain:`.\n- **API not visible / can't enable**\n  - Ensure the correct project. Org policy may restrict consumer APIs; ask an admin or use a personal project.\n- **Org blocks SA keys**\n  - Use installed-app OAuth locally, or set up Workload/Workforce Identity Federation (WIF) for keyless auth.\n- **Leaked SA key**\n  - Immediately delete/rotate the key in Cloud Console. Never commit keys to VCS.\n\n## Dev and tests\n- Unit tests (HTTP mocked) live in `_tests/` and can be run via:\n```bash\npytest backend/app/core/landing_page/google_search_console/_tests -q\n```\n\n## Security\n- Treat all credential files as secrets; do not commit to git.\n- Use least-privilege scopes (`webmasters.readonly` unless you need write operations).\n\n## License\nInternal DealScale component. Replace with your preferred license if extracted as a submodule/repo.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftechwithty%2Fgoogle-search-console-sdk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftechwithty%2Fgoogle-search-console-sdk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftechwithty%2Fgoogle-search-console-sdk/lists"}