0
# Product Reviews Management
1
2
Complete functionality for managing product reviews through the Google Shopping Merchant Reviews API. This service enables CRUD operations on product reviews, including creation, retrieval, listing with pagination, and deletion.
3
4
## Capabilities
5
6
### Client Initialization
7
8
Create product reviews service clients with authentication and configuration options.
9
10
```python { .api }
11
class ProductReviewsServiceClient:
12
def __init__(
13
self,
14
*,
15
credentials: Optional[ga_credentials.Credentials] = None,
16
transport: Optional[Union[str, ProductReviewsServiceTransport, Callable]] = None,
17
client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None,
18
client_info: gapic_v1.client_info.ClientInfo = None
19
):
20
"""
21
Initialize the product reviews service client.
22
23
Args:
24
credentials: Google authentication credentials
25
transport: Transport to use for communication ('grpc', 'grpc_asyncio', 'rest', or transport instance)
26
client_options: Client configuration options
27
client_info: Client information for user agent
28
"""
29
30
class ProductReviewsServiceAsyncClient:
31
def __init__(
32
self,
33
*,
34
credentials: Optional[ga_credentials.Credentials] = None,
35
transport: Optional[Union[str, ProductReviewsServiceTransport, Callable]] = None,
36
client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None,
37
client_info: gapic_v1.client_info.ClientInfo = None
38
):
39
"""
40
Initialize the async product reviews service client.
41
42
Args:
43
credentials: Google authentication credentials
44
transport: Transport to use for communication ('grpc_asyncio' or transport instance)
45
client_options: Client configuration options
46
client_info: Client information for user agent
47
"""
48
```
49
50
### Getting Individual Reviews
51
52
Retrieve a specific product review by its resource name.
53
54
```python { .api }
55
def get_product_review(
56
self,
57
request: Optional[Union[GetProductReviewRequest, dict]] = None,
58
*,
59
name: Optional[str] = None,
60
retry = gapic_v1.method.DEFAULT,
61
timeout = gapic_v1.method.DEFAULT,
62
metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
63
) -> ProductReview:
64
"""
65
Gets a product review.
66
67
Args:
68
request: The request object or dict containing the request fields
69
name: Required. Resource name format: accounts/{account}/productReviews/{productReview}
70
retry: Retry configuration for the request
71
timeout: Timeout for the request in seconds
72
metadata: Additional metadata for the request
73
74
Returns:
75
ProductReview: The requested product review
76
77
Raises:
78
google.api_core.exceptions.NotFound: If the review is not found
79
google.api_core.exceptions.PermissionDenied: If access is denied
80
"""
81
82
async def get_product_review(
83
self,
84
request: Optional[Union[GetProductReviewRequest, dict]] = None,
85
*,
86
name: Optional[str] = None,
87
retry = gapic_v1.method.DEFAULT,
88
timeout = gapic_v1.method.DEFAULT,
89
metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
90
) -> ProductReview:
91
"""Async version of get_product_review."""
92
```
93
94
### Listing Reviews with Pagination
95
96
List product reviews for an account with automatic pagination support.
97
98
```python { .api }
99
def list_product_reviews(
100
self,
101
request: Optional[Union[ListProductReviewsRequest, dict]] = None,
102
*,
103
parent: Optional[str] = None,
104
retry = gapic_v1.method.DEFAULT,
105
timeout = gapic_v1.method.DEFAULT,
106
metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
107
) -> ListProductReviewsPager:
108
"""
109
Lists product reviews for an account.
110
111
Args:
112
request: The request object or dict containing the request fields
113
parent: Required. Parent resource format: accounts/{account}
114
retry: Retry configuration for the request
115
timeout: Timeout for the request in seconds
116
metadata: Additional metadata for the request
117
118
Returns:
119
ListProductReviewsPager: Pager for iterating through reviews
120
121
Raises:
122
google.api_core.exceptions.InvalidArgument: If parent format is invalid
123
google.api_core.exceptions.PermissionDenied: If access is denied
124
"""
125
126
async def list_product_reviews(
127
self,
128
request: Optional[Union[ListProductReviewsRequest, dict]] = None,
129
*,
130
parent: Optional[str] = None,
131
retry = gapic_v1.method.DEFAULT,
132
timeout = gapic_v1.method.DEFAULT,
133
metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
134
) -> ListProductReviewsAsyncPager:
135
"""Async version of list_product_reviews."""
136
```
137
138
### Inserting Reviews
139
140
Insert a product review.
141
142
```python { .api }
143
def insert_product_review(
144
self,
145
request: Optional[Union[InsertProductReviewRequest, dict]] = None,
146
*,
147
retry = gapic_v1.method.DEFAULT,
148
timeout = gapic_v1.method.DEFAULT,
149
metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
150
) -> ProductReview:
151
"""
152
Inserts a product review.
153
154
Args:
155
request: The request object containing parent, product_review, and data_source
156
retry: Retry configuration for the request
157
timeout: Timeout for the request in seconds
158
metadata: Additional metadata for the request
159
160
Returns:
161
ProductReview: The inserted product review
162
163
Raises:
164
google.api_core.exceptions.InvalidArgument: If request data is invalid
165
google.api_core.exceptions.PermissionDenied: If access is denied
166
"""
167
168
async def insert_product_review(
169
self,
170
request: Optional[Union[InsertProductReviewRequest, dict]] = None,
171
*,
172
retry = gapic_v1.method.DEFAULT,
173
timeout = gapic_v1.method.DEFAULT,
174
metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
175
) -> ProductReview:
176
"""Async version of insert_product_review."""
177
```
178
179
### Deleting Reviews
180
181
Delete a product review permanently.
182
183
```python { .api }
184
def delete_product_review(
185
self,
186
request: Optional[Union[DeleteProductReviewRequest, dict]] = None,
187
*,
188
name: Optional[str] = None,
189
retry = gapic_v1.method.DEFAULT,
190
timeout = gapic_v1.method.DEFAULT,
191
metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
192
) -> None:
193
"""
194
Deletes a product review.
195
196
Args:
197
request: The request object or dict containing the request fields
198
name: Required. Resource name format: accounts/{account}/productReviews/{productReview}
199
retry: Retry configuration for the request
200
timeout: Timeout for the request in seconds
201
metadata: Additional metadata for the request
202
203
Raises:
204
google.api_core.exceptions.NotFound: If the review is not found
205
google.api_core.exceptions.PermissionDenied: If access is denied
206
"""
207
208
async def delete_product_review(
209
self,
210
request: Optional[Union[DeleteProductReviewRequest, dict]] = None,
211
*,
212
name: Optional[str] = None,
213
retry = gapic_v1.method.DEFAULT,
214
timeout = gapic_v1.method.DEFAULT,
215
metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
216
) -> None:
217
"""Async version of delete_product_review."""
218
```
219
220
### Helper Methods
221
222
Resource path construction and parsing utilities.
223
224
```python { .api }
225
@classmethod
226
def product_review_path(cls, account: str, name: str) -> str:
227
"""
228
Returns a fully-qualified product review string.
229
230
Args:
231
account: Account ID
232
name: Product review name/ID
233
234
Returns:
235
str: Resource path in format accounts/{account}/productReviews/{productReview}
236
"""
237
238
@classmethod
239
def parse_product_review_path(cls, path: str) -> Dict[str, str]:
240
"""
241
Parses a product review path.
242
243
Args:
244
path: Product review resource path
245
246
Returns:
247
Dict[str, str]: Dictionary with 'account' and 'product_review' keys
248
249
Raises:
250
ValueError: If path format is invalid
251
"""
252
253
@classmethod
254
def from_service_account_file(
255
cls,
256
filename: str,
257
*args,
258
**kwargs
259
) -> ProductReviewsServiceClient:
260
"""
261
Creates a client from a service account file.
262
263
Args:
264
filename: Path to service account JSON file
265
*args: Additional arguments to pass to constructor
266
**kwargs: Additional keyword arguments to pass to constructor
267
268
Returns:
269
ProductReviewsServiceClient: Configured client instance
270
"""
271
272
@classmethod
273
def from_service_account_info(
274
cls,
275
info: dict,
276
*args,
277
**kwargs
278
) -> ProductReviewsServiceClient:
279
"""
280
Creates a client from service account info.
281
282
Args:
283
info: Service account info dictionary
284
*args: Additional arguments to pass to constructor
285
**kwargs: Additional keyword arguments to pass to constructor
286
287
Returns:
288
ProductReviewsServiceClient: Configured client instance
289
"""
290
```
291
292
## Usage Examples
293
294
### Basic Product Review Management
295
296
```python
297
from google.shopping.merchant_reviews import (
298
ProductReviewsServiceClient,
299
ProductReview,
300
ProductReviewAttributes,
301
InsertProductReviewRequest
302
)
303
from google.auth import default
304
from google.protobuf.timestamp_pb2 import Timestamp
305
import time
306
307
# Initialize client
308
credentials, project = default()
309
client = ProductReviewsServiceClient(credentials=credentials)
310
311
# Create a new product review
312
review_attributes = ProductReviewAttributes(
313
reviewer_username="happy_customer",
314
reviewer_id="reviewer456",
315
content="This product exceeded my expectations! Great quality and fast shipping.",
316
title="Excellent product!",
317
rating=5.0,
318
min_rating=1,
319
max_rating=5,
320
product_names=["Wireless Bluetooth Headphones"],
321
brands=["AudioTech"],
322
gtins=["1234567890123"],
323
is_verified_purchase=True,
324
collection_method=ProductReviewAttributes.CollectionMethod.POST_FULFILLMENT
325
)
326
327
# Set review time
328
review_time = Timestamp()
329
review_time.FromSeconds(int(time.time()))
330
review_attributes.review_time = review_time
331
332
product_review = ProductReview(
333
product_review_id="product-review-789",
334
product_review_attributes=review_attributes
335
)
336
337
# Insert the review
338
request = InsertProductReviewRequest(
339
parent="accounts/your-account-id",
340
product_review=product_review,
341
data_source="accounts/your-account-id/dataSources/your-datasource-id"
342
)
343
344
result = client.insert_product_review(request=request)
345
print(f"Inserted product review: {result.name}")
346
347
# List product reviews
348
reviews = client.list_product_reviews(parent="accounts/your-account-id")
349
for review in reviews:
350
print(f"Product Review ID: {review.product_review_id}")
351
print(f"Rating: {review.product_review_attributes.rating}")
352
print(f"Product: {review.product_review_attributes.product_names[0] if review.product_review_attributes.product_names else 'N/A'}")
353
354
# Get specific product review
355
review_name = f"accounts/your-account-id/productReviews/product-review-789"
356
specific_review = client.get_product_review(name=review_name)
357
print(f"Retrieved product review rating: {specific_review.product_review_attributes.rating}")
358
359
# Delete product review
360
client.delete_product_review(name=review_name)
361
print("Product review deleted")
362
```
363
364
### Advanced Product Review with Multiple Attributes
365
366
```python
367
# Create comprehensive product review with multiple attributes
368
review_attributes = ProductReviewAttributes(
369
aggregator_name="ReviewPlatform",
370
publisher_name="TechReviews Inc",
371
reviewer_username="tech_expert_2024",
372
reviewer_id="expert789",
373
title="Comprehensive Analysis of Wireless Headphones",
374
content="After using these headphones for 3 months, I can confidently say they deliver exceptional audio quality...",
375
pros=["Excellent sound quality", "Long battery life", "Comfortable fit"],
376
cons=["Could use better noise cancellation", "Price is a bit high"],
377
rating=4.2,
378
min_rating=1,
379
max_rating=5,
380
product_names=["Premium Wireless Bluetooth Headphones", "Model XYZ-2024"],
381
product_links=["https://example.com/product/xyz-2024"],
382
brands=["AudioTech", "PremiumSound"],
383
gtins=["1234567890123"],
384
mpns=["XYZ-2024-BLK"],
385
skus=["AUDIO-XYZ-BLK"],
386
asins=["B08EXAMPLE"],
387
is_verified_purchase=True,
388
is_spam=False,
389
is_incentivized_review=False,
390
collection_method=ProductReviewAttributes.CollectionMethod.POST_FULFILLMENT,
391
transaction_id="txn-abc123456",
392
review_language="en",
393
review_country="US"
394
)
395
396
# Set review time
397
review_time = Timestamp()
398
review_time.FromSeconds(int(time.time() - 86400)) # 1 day ago
399
review_attributes.review_time = review_time
400
401
product_review = ProductReview(
402
product_review_id="comprehensive-review-001",
403
product_review_attributes=review_attributes
404
)
405
406
# Insert comprehensive review
407
request = InsertProductReviewRequest(
408
parent="accounts/your-account-id",
409
product_review=product_review,
410
data_source="accounts/your-account-id/dataSources/comprehensive-reviews"
411
)
412
413
result = client.insert_product_review(request=request)
414
print(f"Inserted comprehensive product review: {result.name}")
415
```
416
417
### Async Product Review Operations
418
419
```python
420
import asyncio
421
from google.shopping.merchant_reviews import ProductReviewsServiceAsyncClient
422
423
async def analyze_product_reviews():
424
client = ProductReviewsServiceAsyncClient()
425
426
# Get all product reviews asynchronously
427
reviews = await client.list_product_reviews(
428
parent="accounts/your-account-id"
429
)
430
431
# Calculate average rating
432
total_rating = 0
433
count = 0
434
low_rated_reviews = []
435
436
async for review in reviews:
437
rating = review.product_review_attributes.rating
438
if rating > 0: # Only count reviews with ratings
439
total_rating += rating
440
count += 1
441
442
if rating < 3.0:
443
low_rated_reviews.append(review)
444
445
if count > 0:
446
average_rating = total_rating / count
447
print(f"Average product rating: {average_rating:.2f}")
448
print(f"Total reviews: {count}")
449
print(f"Low-rated reviews: {len(low_rated_reviews)}")
450
451
# Process low-rated reviews
452
for review in low_rated_reviews:
453
print(f"Low rating alert: {review.product_review_id} - {review.product_review_attributes.rating}")
454
455
# Run async analysis
456
asyncio.run(analyze_product_reviews())
457
```
458
459
## Types
460
461
```python { .api }
462
# Request types
463
class GetProductReviewRequest:
464
name: str # Required: accounts/{account}/productReviews/{productReview}
465
466
class DeleteProductReviewRequest:
467
name: str # Required: accounts/{account}/productReviews/{productReview}
468
469
class ListProductReviewsRequest:
470
parent: str # Required: accounts/{account}
471
page_size: int # Optional: maximum results per page
472
page_token: str # Optional: pagination token
473
474
class InsertProductReviewRequest:
475
parent: str # Required: accounts/{account}
476
product_review: ProductReview # Required: review to insert
477
data_source: str # Required: accounts/{account}/dataSources/{datasource}
478
479
# Response types
480
class ListProductReviewsResponse:
481
product_reviews: MutableSequence[ProductReview]
482
next_page_token: str
483
@property
484
def raw_page(self) -> ListProductReviewsResponse: ...
485
```