App Reviews
Typed review ingestion and app metadata for the Apple App Store and Google Play Store with one Python package.
Why App Reviews?
Each store has a different API, authentication and data format. This package puts both behind one interface.
- No credentials to start. The default sources are public endpoints.
- Both stores, one API.
AppStoreReviewsandGooglePlayReviewsfollow the same pattern. - Apple storefront fetch. Fetch public RSS reviews across storefronts in a single call; Google Play reviews remain global.
- Optional authenticated access. Plug in App Store Connect or Google Play Developer API credentials for account-scoped review access.
- Developer replies. Create or replace and read replies on both stores; delete replies on Apple. Requires official API credentials. See Replies.
- Version history and release notes. Read public App Store release history or owned-app versions from App Store Connect. See Version history and AppStoreVersions.
- Minimal dependencies.
cryptographyfor JWT signing andhttpxfor transport. - Real async. Every entry point has an async twin (
afetch,aiter_reviews,aiter_pages,asearch, ...) usinghttpx.AsyncClient, not a thread-pool wrapper. See Async. - Streams or buffers, your choice.
fetch()sorts and filters the whole corpus;iter_reviews()yields reviews as they arrive so a 155-storefront walk never has to fit in memory. See Paging and cursors. - Pooled connections. Clients reuse
httpxconnection pools across requests, avoiding a new connection for every page when the server permits reuse. - Retries, timeouts and proxies. Configured per client through
RetryConfigandproxy=. - JSON-ready output.
to_dict()preserves reviews and diagnostics;to_dicts()returns review rows for JSONL or CSV. - Typed and tested. Strict mypy, and coverage held at 85% or above.
Quick Example
Apple App Store:
from app_reviews import AppStoreReviews, Country
with AppStoreReviews() as client:
result = client.fetch(
"324684580",
countries=[Country.US],
limit=20,
max_pages=2,
)
for review in result:
print(f"[{review.country}] {review.rating}* {review.title}")
Google Play Store:
from app_reviews import GooglePlayReviews
# Play has one global review corpus, so there is no country to fan out over.
with GooglePlayReviews() as client:
result = client.fetch("com.spotify.music", limit=20, max_pages=2)
for review in result:
print(f"{review.rating}* {review.body[:80]}")
Both return a FetchResult containing reviews and any per-country errors. FetchResult is iterable: loop over it directly to get Review objects.
Limitations
- How far back you can reach differs by source
appstore_scraper: ~500 most recent reviews per storefrontgoogleplay_official: the last 7 days only; full history needs a Play Console CSV export, which this package does not readappstore_official,googleplay_scraper: no package-imposed history window; upstream availability still applies
- The Google Play web endpoint is undocumented and rate-limited, and can change without notice
- Authenticated APIs require developer accounts
- Apple Developer Program: $99/year
- Google Play Developer account: $25 one-time
Per-source detail: How the sources differ.
Next Steps
- Installation: install the package
- Quick Start: your first fetch, both stores
- Python API: full API reference
- How It Works: what the fetch pipeline does
- Comparison: choose between this package and focused clients
- FAQ: direct answers about countries, limits, and credentials