The go-to Python package for App Store and Google Play review extraction
Project description
App Reviews
Fetch reviews, search apps, and look up metadata from the Apple App Store and Google Play Store.
Why App Reviews?
Apple and Google use completely different APIs, formats, and auth methods. App Reviews handles all of this behind a simple Python API -- no API keys required.
from app_reviews import AppStoreSearch, GooglePlayReviews, Country
# Search for apps
results = AppStoreSearch().search("whatsapp", country=Country.US, limit=5)
print(results[0].name, results[0].icon_url)
# Fetch reviews
reviews = GooglePlayReviews().fetch("com.whatsapp", countries=[Country.US])
for review in reviews:
print(f"{review.rating}* {review.body[:80]}")
Highlights
| Both stores | Apple App Store + Google Play in one package |
| Search & lookup | Find apps by keyword, look up metadata by ID |
| No API keys | Works out of the box using public endpoints |
| 155 countries | Fetch across regions in a single call |
| Official APIs | Optionally use App Store Connect or Google Play Developer API |
| Interactive TUI | Browse reviews in the terminal |
| Export | JSON, JSONL, CSV |
| Minimal deps | Just cryptography for JWT + stdlib urllib |
Install
pip install app-reviews
Or with uv:
uv add app-reviews
Quick Start
Apple App Store
from app_reviews import AppStoreReviews, Country
client = AppStoreReviews()
result = client.fetch("324684580", countries=[Country.US, Country.GB])
for review in result:
print(f"[{review.country}] {review.rating}* {review.title}")
Google Play Store
from app_reviews import GooglePlayReviews, Country
client = GooglePlayReviews()
result: FetchResult = client.fetch("com.instagram.android", countries=[Country.US])
for review in result:
print(f"[{review.country}] {review.rating}* {review.body[:80]}")
Review
fetch() returns a FetchResult containing Review objects:
| Field | Type | Description |
|---|---|---|
id |
str |
Unique review identifier |
store |
Store |
"appstore" or "googleplay" |
app_id |
str |
App Store ID or package name |
country |
str |
Two-letter country code |
rating |
int |
Star rating (1 -- 5) |
title |
str |
Review title (may be empty for Google Play) |
body |
str |
Review text |
author_name |
str |
Reviewer display name |
app_version |
str | None |
App version at time of review |
created_at |
datetime |
When the review was posted |
updated_at |
datetime | None |
When the review was last edited |
is_edited |
bool |
Whether the review was edited |
source |
Source |
Provider (e.g. "appstore_scraper", "googleplay_official") |
language |
str | None |
Review language code |
fetched_at |
datetime | None |
When the review was fetched |
Search & Lookup
Find apps by keyword and look up app metadata -- no authentication required.
Search
from app_reviews import AppStoreSearch, GooglePlaySearch, Country, AppMetadata
# App Store -- returns list[AppMetadata]
results: list[AppMetadata] = AppStoreSearch().search("fitness tracker", country=Country.US, limit=10)
for app in results:
print(f"{app.name} by {app.developer} ({app.rating}*)")
# Google Play -- returns list[AppMetadata]
results: list[AppMetadata] = GooglePlaySearch().search("fitness tracker", country=Country.US, limit=10)
for app in results:
print(f"{app.name} by {app.developer}")
Lookup
# Look up by bundle ID (App Store) or package name (Google Play)
# Returns AppMetadata | None
app = AppStoreSearch().lookup("com.burbn.instagram")
if app:
print(f"{app.name} - {app.icon_url}")
app = GooglePlaySearch().lookup("com.whatsapp")
if app:
print(f"{app.name} - {app.rating}*")
AppMetadata
Both search() and lookup() return AppMetadata objects:
| Field | Type | Description |
|---|---|---|
app_id |
str |
Bundle ID (App Store) or package name (Google Play) |
name |
str |
App display name |
developer |
str |
Developer or publisher name |
category |
str |
Primary category (e.g. "Social Networking") |
price |
str |
Formatted price (e.g. "Free", "$4.99") |
version |
str |
Current version string |
rating |
float |
Average star rating (0.0 -- 5.0) |
rating_count |
int |
Total number of ratings |
url |
str |
Store page URL |
icon_url |
str | None |
App icon image URL |
Authentication (Optional)
For higher limits and more data, use the official APIs with your developer credentials.
Requires an Apple Developer Program membership ($99/year).
from app_reviews import AppStoreReviews, AppStoreAuth, Country
auth = AppStoreAuth(
key_id="ABC123DEF4",
issuer_id="12345678-1234-1234-1234-123456789012",
key_path="/path/to/AuthKey.p8",
)
client = AppStoreReviews(auth=auth)
result = client.fetch("324684580", countries=[Country.US, Country.GB])
Requires a Google Play Developer account ($25 one-time).
from app_reviews import GooglePlayReviews, GooglePlayAuth, Country
auth = GooglePlayAuth(service_account_path="/path/to/service-account.json")
client = GooglePlayReviews(auth=auth)
result = client.fetch("com.instagram.android", countries=[Country.US])
Advanced Usage
from app_reviews import AppStoreReviews, RetryConfig
retry = RetryConfig(
max_retries=5, # default: 3
backoff_factor=1.0, # default: 0.5
timeout=60.0, # default: 30.0
retry_on=[429, 503], # default: [500, 502, 503, 504, 429]
)
client = AppStoreReviews(retry=retry, proxy="http://proxy.example.com:8080")
result = client.fetch("324684580", countries=["us"])
from app_reviews import GooglePlayReviews
from app_reviews.exporters.json import export_json
from app_reviews.exporters.csv import export_csv
from app_reviews.exporters.jsonl import export_jsonl
client = GooglePlayReviews()
result = client.fetch("com.instagram.android")
export_json(result.reviews) # JSON array string
export_csv(result.reviews) # CSV string with headers
export_jsonl(result.reviews) # one JSON object per line
Browse reviews in the terminal with the built-in TUI:
pip install app-reviews[tui]
app-reviews
Limitations
-
Free scrapers have limits:
- App Store RSS: ~500 most recent reviews.
- Google Play scraper: rate-limited and may not return all reviews.
-
No historical data:
- Only the most recent reviews from public endpoints
-
Official APIs require developer accounts:
- Apple ($99/year), Google ($25 one-time)
Documentation
Read the full docs includes guides on the Python API, TUI, authentication, export formats, and architecture.
Contributing
git clone https://github.com/firattamurcw/app-reviews.git
cd app-reviews
uv sync --group dev
make test
See the Contributing Guide · Code of Conduct · Security Policy
Acknowledgements
The Google Play scraping logic (parsing AF_initDataCallback datasets, field index paths) is based on the work done in google-play-scraper by JoMingyu. We re-implemented it on top of our own HTTP layer to support retries and proxies, but the data-structure knowledge originates from that project.
License
Project details
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 app_reviews-0.4.0.tar.gz.
File metadata
- Download URL: app_reviews-0.4.0.tar.gz
- Upload date:
- Size: 159.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9ab94432128203d5ae197cd27bb9a579db7d4d5fe407d465cf3a279abc3a5eab
|
|
| MD5 |
829c9762a2ee4c33d37081d4cc780cba
|
|
| BLAKE2b-256 |
915d874a621ceef48115e457153fee2f9719a49a069722e68e990520836a244d
|
Provenance
The following attestation bundles were made for app_reviews-0.4.0.tar.gz:
Publisher:
release.yml on firattamurcw/app-reviews
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
app_reviews-0.4.0.tar.gz -
Subject digest:
9ab94432128203d5ae197cd27bb9a579db7d4d5fe407d465cf3a279abc3a5eab - Sigstore transparency entry: 1263426126
- Sigstore integration time:
-
Permalink:
firattamurcw/app-reviews@e640237ad8c234c33322f6b87901313bdcedac79 -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/firattamurcw
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@e640237ad8c234c33322f6b87901313bdcedac79 -
Trigger Event:
push
-
Statement type:
File details
Details for the file app_reviews-0.4.0-py3-none-any.whl.
File metadata
- Download URL: app_reviews-0.4.0-py3-none-any.whl
- Upload date:
- Size: 59.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
61223a4d3d5b0d77267b0e7cf0e075941508984a8f4793a1b7951cd399b804a2
|
|
| MD5 |
5e48553b44fd316cae32a38c87b6a40d
|
|
| BLAKE2b-256 |
88c38907965977ae6c52fec0ac4bc11683bb8804a77094d58131238415a57321
|
Provenance
The following attestation bundles were made for app_reviews-0.4.0-py3-none-any.whl:
Publisher:
release.yml on firattamurcw/app-reviews
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
app_reviews-0.4.0-py3-none-any.whl -
Subject digest:
61223a4d3d5b0d77267b0e7cf0e075941508984a8f4793a1b7951cd399b804a2 - Sigstore transparency entry: 1263426232
- Sigstore integration time:
-
Permalink:
firattamurcw/app-reviews@e640237ad8c234c33322f6b87901313bdcedac79 -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/firattamurcw
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@e640237ad8c234c33322f6b87901313bdcedac79 -
Trigger Event:
push
-
Statement type: