A lightweight Python client for Google Business Profile reviews and locations (non-official)
Project description
google-reviews-client
A lightweight, non-official Python client for the Google Business Profile API: accounts, locations, and reviews.
Not affiliated with Google. This library isn't an official Google product. Google, Google Maps, and related marks are trademarks of Google LLC.
Features
- Incremental sync - fetch only new or updated reviews
- Auth-agnostic - accepts any
google.auth.credentials.Credentials(OAuth2, service account, etc.) - CLI included - fetch and save reviews from the terminal with a single command
- Minimal dependencies - only
httpxandgoogle-authat runtime
Prerequisites
Before you can use this project, you'll need:
- A Google Business Profile - owner or manager access to a verified business listing on Google, active for at least 60 days
- A Google Cloud project - this is where your API credentials live
- API access approval - Google requires a formal application, then you enable the APIs
- OAuth credentials - configure the consent screen and download a JSON file for authentication
If you already have all of these, skip to Installation. Otherwise, follow the steps below - they walk you through everything.
1. Set up your Google Business Profile
You need to be an owner or manager of a verified business listing that's been active for at least 60 days before you can request API access.
If you don't have a listing yet:
- Go to business.google.com and sign in with your Google account
- Click Add your business to Google and follow the prompts
- Google will ask you to verify ownership - this usually happens via postcard, phone, or email
- Wait for verification (up to 5 business days) and then 60 more days before you can request API access
If your business is already on Google Maps but you haven't claimed it, search for it on Google Maps, click your business, and select Claim this business.
2. Create a Google Cloud project
A Google Cloud project is a container for your API credentials. You don't need to pay anything - the free tier is enough.
- Go to console.cloud.google.com/projectcreate
- Give it a name (e.g., "My Business Reviews") and click Create
- Note your project number from the project dashboard, you'll need it in the next step
3. Get API access approval and enable the APIs
The Business Profile API is not open to everyone - Google reviews each application.
Apply for access:
- Go to the API access request form
- Select "Application for Basic API Access" from the dropdown
- Use the same email that's an owner or manager on your Business Profile
- Enter your project number from step 2 and your company website URL
You'll get an email within 5 business days. You can also check your status in Cloud Console → APIs → Quotas for the Account Management API: 0 requests per minute means pending, 300 requests per minute means approved.
After approval, enable these APIs in the API Library:
- My Business Account Management API (accounts and locations)
- Google My Business API (reviews) — this one is private and only appears in the API Library after your access is approved
For each one: search by name → click on it → click Enable.
4. Set up OAuth credentials
You need to configure the OAuth consent screen (what users see when they log in) and create a credentials file (what the CLI uses to start the authentication flow).
Configure the consent screen:
- Go to APIs & Services > OAuth consent screen
- Choose External user type and click Create
- Fill in the App name (anything you like) and your email address
- You can skip the Scopes step - the CLI requests the right scopes automatically
- Under Test users, click Add users and enter your Google account email
- Click Save and Continue through the remaining steps
Important: You must add yourself as a test user. Without this, you'll get an "Access blocked" error when trying to log in.
Create OAuth credentials:
- Go to APIs & Services > Credentials
- Click Create Credentials > OAuth client ID
- Choose Desktop application as the application type
- Give it a name (e.g., "Reviews CLI") and click Create
- Click Download JSON and save the file in the directory where you'll run the CLI
The downloaded file will be named something like
client_secret_123456.apps.googleusercontent.com.json- the CLI auto-detects it, so you don't need to rename it.
Installation
pip install google-reviews-client
Or with uv:
uv add google-reviews-client
Quick Start
CLI
With uv installed, run directly without installing:
uvx 'google-reviews-client[cli]'
Or install it first, then run:
pip install 'google-reviews-client[cli]'
google-reviews-client
The CLI authenticates via browser-based OAuth, fetches your reviews, prints them to the terminal, and saves them as JSONL.
# First run — auto-detect client secrets, run OAuth, select accounts/locations
google-reviews-client
# Subsequent runs — auto-sync all saved targets
google-reviews-client
# Specify client secrets file for first-time setup
google-reviews-client --client-secrets-file /path/to/client_secret.json
# Use a specific config file
google-reviews-client --config-file google-reviews-config.123.user@gmail.com.json
# Set language for reviews (saved per-location in config)
google-reviews-client --language pt-BR
# Verbose mode — shows file search details and full error tracebacks
google-reviews-client -v
First run
On first run, a browser window opens for Google OAuth. After granting consent, the CLI prompts you to select accounts
and locations, then creates a config file (e.g., google-reviews-config.76944426795.user@gmail.com.json) with your
credentials and selections.
You can select multiple accounts and locations — the CLI will sync all of them on each run.
Subsequent runs
On subsequent runs, the CLI auto-detects config files in the current directory and syncs all configured targets:
google-reviews-client v0.1.0
Directory: /Users/you/reviews
Using config: google-reviews-config.76944426795.user@gmail.com.json
My Business > My Coffee Shop
Syncing reviews since 2024-01-15T00:00:00...
Date Rating Review Reviewer Replied
------------------------------------------------------------------------------------------
2024-01-20 ⭐⭐⭐⭐⭐ Amazing coffee! John D. No
Done! 1 new reviews saved to reviews-456.jsonl
Config file
The config file stores your OAuth credentials and selected accounts/locations:
{
"credentials": { "..." },
"targets": [
{
"account": "accounts/123",
"account_name": "My Business",
"locations": [
{
"location": "locations/456",
"title": "My Coffee Shop",
"language": "pt-BR"
}
]
}
]
}
To change your selections, edit the config file:
- Remove a location from
locationsto stop syncing it - Remove all targets to be prompted again on next run
- Remove
languagefrom a location to use the default - Delete the config file entirely to start fresh (re-authenticate and re-select)
Programmatic Usage
from google.oauth2.credentials import Credentials
from google_reviews_client import GoogleReviewsClient
# Create credentials (see "Authentication" section below)
creds = Credentials(
token="your-access-token",
refresh_token="your-refresh-token",
token_uri="https://oauth2.googleapis.com/token",
client_id="your-client-id",
client_secret="your-client-secret",
)
client = GoogleReviewsClient(credentials=creds)
# Discover accounts and locations
accounts = client.list_accounts()
locations = client.list_locations(accounts[0].name)
# Fetch reviews (lazy iterator - pages fetched on demand)
for review in client.list_reviews(locations[0].full_name):
print(f"{review.rating_value}/5 - {review.reviewer.display_name}")
print(f" {review.comment}")
Authentication
The library accepts any google.auth.credentials.Credentials instance. Here are common ways to create credentials:
From saved tokens
If you have OAuth2 tokens (e.g., from a previous authorization flow):
from google.oauth2.credentials import Credentials
creds = Credentials(
token="your-access-token",
refresh_token="your-refresh-token",
token_uri="https://oauth2.googleapis.com/token",
client_id="your-client-id",
client_secret="your-client-secret",
)
From a service account
from google.oauth2 import service_account
creds = service_account.Credentials.from_service_account_file(
"service-account.json",
scopes=["https://www.googleapis.com/auth/business.manage"],
)
Browser-based OAuth flow
For interactive scripts, use google-auth-oauthlib:
pip install google-auth-oauthlib
from google_auth_oauthlib.flow import InstalledAppFlow
flow = InstalledAppFlow.from_client_secrets_file(
"credentials.json",
scopes=["https://www.googleapis.com/auth/business.manage"],
)
creds = flow.run_local_server(port=0)
Usage Examples
List accounts and locations
accounts = client.list_accounts()
for account in accounts:
print(f"Account: {account.account_name} ({account.name})")
locations = client.list_locations(account.name)
for location in locations:
print(f" Location: {location.title} ({location.full_name})")
Fetch all reviews
for review in client.list_reviews(location.full_name):
print(f"{review.rating_value}/5 by {review.reviewer.display_name}")
print(f" Posted: {review.create_time}")
if review.comment:
print(f" Comment: {review.comment}")
if review.has_reply:
print(f" Reply: {review.review_reply.comment}")
Incremental sync
Fetch only reviews updated after a specific timestamp:
from datetime import datetime, timezone
last_sync = datetime(2024, 1, 1, tzinfo=timezone.utc)
for review in client.list_reviews(location.full_name, update_time=last_sync):
print(f"New/updated: {review.review_id} - {review.rating_value}/5")
Error handling
from google_reviews_client import (
GoogleReviewsClient,
AuthenticationError,
GooglePermissionError,
RateLimitError,
NotFoundError,
)
try:
reviews = list(client.list_reviews(location.full_name))
except AuthenticationError:
print("Authentication failed. Check your credentials.")
except GooglePermissionError:
print("Insufficient permissions. Check your account access.")
except RateLimitError as e:
print(f"Rate limited. Retry after {e.retry_after} seconds.")
except NotFoundError:
print("Location not found. Check the location ID.")
Serialize reviews to JSON
import json
reviews = [review.to_dict() for review in client.list_reviews(location.full_name)]
with open("reviews.json", "w") as f:
json.dump(reviews, f, indent=2, ensure_ascii=False)
API Reference
Client
| Method | Returns | Description |
|---|---|---|
list_accounts() |
list[Account] |
Discover accessible Google Business accounts |
list_locations(account) |
list[Location] |
List locations under an account |
list_reviews(location, *, update_time=None) |
Iterator[Review] |
Fetch reviews with lazy pagination |
Models
| Model | Key Fields |
|---|---|
Account |
name, account_name, type |
Location |
location_id, account_id, title, full_name (property) |
Review |
review_id, star_rating, comment, create_time, update_time, reviewer, review_reply |
Reviewer |
display_name, profile_photo_url, is_anonymous |
ReviewReply |
comment, update_time |
StarRating |
Enum: ONE through FIVE |
Exceptions
| Exception | Trigger |
|---|---|
GoogleReviewsError |
Base exception for all library errors |
AuthenticationError |
401 - invalid or expired credentials |
GooglePermissionError |
403 - insufficient permissions |
NotFoundError |
404 - resource not found |
RateLimitError |
429 - rate limit exceeded (has retry_after attribute) |
GoogleAPIError |
5xx - Google API server error |
HTTPError |
Transport-level HTTP error (non-2xx, before domain mapping) |
ValidationError |
Invalid parameters |
Contributing
See CONTRIBUTING.md for development setup and guidelines.
License
This project is licensed under the terms of the MIT License.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file google_reviews_client-0.3.0.tar.gz.
File metadata
- Download URL: google_reviews_client-0.3.0.tar.gz
- Upload date:
- Size: 21.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e07641672a0e7dca19bb3f8e1c06a951a8f85e36c2f8521d11f75811fed510f7
|
|
| MD5 |
ffa3512a9830313e8b430bc74e488406
|
|
| BLAKE2b-256 |
1b60fa35bf12021b0af6cdfe548381fe82b5d239a508ca9e954d25d9e93e4ffa
|
File details
Details for the file google_reviews_client-0.3.0-py3-none-any.whl.
File metadata
- Download URL: google_reviews_client-0.3.0-py3-none-any.whl
- Upload date:
- Size: 25.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a4250dacf9916b4b27419a3672a3928702064a47dccdf2e679f16bcffdf03bbe
|
|
| MD5 |
626e3053ca7166fd216de4ca2adfd7de
|
|
| BLAKE2b-256 |
5eb3d70aa66021eb9d376b7ad1b743ec14630ac6ea191a47f93dcf3074147f9c
|