Playfast ⚡
Lightning-Fast Google Play Store Scraper
Playfast is a high-performance Google Play Store scraper built with Rust + PyO3, delivering 5-10x faster performance with true parallel batch processing.
✨ Features
Play Store Scraping
- 🚀 Blazingly Fast: Batch API is 5-10x faster than sequential
- ⚡ True Parallel: Rust core completely releases GIL
- 🦀 Pure Rust: HTTP + parsing all in Rust for maximum performance
- 🔒 Type Safe: Full Pydantic validation and type hints
- 💾 Memory Efficient: Only 1.5 KB per app, linear scaling
- 🌍 Multi-Country: 247 countries, 93 unique Play Stores
- 📦 Batch API: High-level functions for easy parallel processing
APK Download (NEW!)
- ⬇️ Direct Download: Download APKs directly from Google Play Store
- 🔐 Smart Authentication: OAuth → AAS token exchange with auto-retry
- 💾 Credential Management: Save and reuse authentication tokens
- 🎯 Version Control: Download specific versions or latest
- ⚡ Parallel Downloads: Efficient batch downloading with ThreadPoolExecutor
APK/DEX Analysis
- 🔍 Entry Point Analysis: Identify Activities, Services, deeplink handlers
- 📊 Call Graph: Method-to-method relationship tracking
- 🌐 WebView Flow: Track paths from entry points to WebView APIs
- 🔗 Data Flow: Intent → WebView.loadUrl() data tracking
- 🛡️ Security Analysis: Deeplink vulnerability detection
📊 Performance
Batch Processing makes bulk operations 5-10x faster through true Rust parallelism!
| Method | Time | Speedup |
|---|---|---|
| Batch API | ~3s | 6-8x 🚀 |
| RustClient + ThreadPool | ~3-4s | 6-7x |
| AsyncClient (concurrent) | ~3-5s | 5-7x |
| Sequential | ~20-30s | 1x |
Benchmark: Fetching 3 apps across 3 countries (9 requests total)
🚀 Quick Start
Installation
Using pip (traditional):
pip install playfast
Using uv (recommended - faster):
uv add playfast
Using poetry:
poetry add playfast
Option 1: Batch API (Recommended - Easiest & Fastest)
from playfast import fetch_apps
# Fetch multiple apps across countries (parallel!)
apps = fetch_apps(
app_ids=["com.spotify.music", "com.netflix.mediaclient"],
countries=["us", "kr", "jp"],
)
print(f"Fetched {len(apps)} apps in ~3 seconds!")
Option 2: RustClient (Maximum Performance)
from playfast import RustClient
client = RustClient()
# Get app information (GIL-free!)
app = client.get_app("com.spotify.music")
print(f"{app.title}: {app.score}⭐ ({app.ratings:,} ratings)")
# Get reviews
reviews, next_token = client.get_reviews("com.spotify.music")
for review in reviews[:5]:
print(f"{review.user_name}: {review.score}⭐")
Option 3: AsyncClient (Easy Async)
import asyncio
from playfast import AsyncClient
async def main():
async with AsyncClient() as client:
app = await client.get_app("com.spotify.music")
print(f"{app.title}: {app.score}⭐")
asyncio.run(main())
Option 4: APK Download (NEW!)
from playfast import ApkDownloader
# First-time setup with OAuth token
downloader = ApkDownloader(
email="user@gmail.com", oauth_token="oauth2_4/..." # Get from Google embedded setup
)
downloader.login()
downloader.save_credentials("~/.playfast/credentials.json")
# Subsequent use - just load credentials
downloader = ApkDownloader.from_credentials("~/.playfast/credentials.json")
# Download APK
apk_path = downloader.download("com.instagram.android")
print(f"Downloaded to: {apk_path}")
# Download specific version
apk_path = downloader.download("com.whatsapp", version_code=450814)
Option 5: APK/DEX Analysis
from playfast import ApkAnalyzer
# High-level API
analyzer = ApkAnalyzer("app.apk")
manifest = analyzer.manifest
classes = analyzer.classes
print(f"Package: {manifest.package_name}")
print(f"Activities: {len(manifest.activities)}")
print(f"Classes: {len(classes)}")
# Advanced: WebView flow analysis (low-level API)
from playfast.core import analyze_webview_flows_from_apk
flows = analyze_webview_flows_from_apk("app.apk", max_depth=10)
for flow in flows:
print(f"{flow.entry_point} → {flow.webview_method}")
if flow.is_deeplink_handler:
print(" ⚠️ DEEPLINK HANDLER")
Complete Workflow: Download → Analyze
from playfast import ApkDownloader, ApkAnalyzer
# Download APK from Google Play
downloader = ApkDownloader.from_credentials("~/.playfast/credentials.json")
apk_path = downloader.download("com.instagram.android")
# Analyze the downloaded APK
analyzer = ApkAnalyzer(apk_path)
manifest = analyzer.manifest
print(f"📦 {manifest.package_name}")
print(f"🔢 Version: {manifest.version_name} ({manifest.version_code})")
print(f"📱 Activities: {len(manifest.activities)}")
print(f"🔐 Permissions: {len(manifest.permissions)}")
📚 Examples
See the examples/ directory for more:
Play Store Scraping
01_async_client.py- AsyncClient basics02_rust_client.py- RustClient for max performance03_batch_api.py- High-level batch API04_countries_and_categories.py- Country optimization
APK Download
download/auth_setup.py- Interactive authentication setupdownload/download_apk.py- Download APKs with CLIdownload/batch_download.py- Parallel batch downloading
APK/DEX Analysis
apk/basic.py- ApkAnalyzer high-level APIapk/entry_point_demo.py- Entry point & deeplink detectionapk/call_graph_demo.py- Method call relationship analysisapk/security_audit.py- Security auditwebview/flow_demo.py- Complete WebView flow analysiswebview/high_level_api.py- High-level ApkAnalyzer API
📖 Documentation
Play Store Scraping
- Getting Started - Installation and first steps
- Quick Start - Practical examples
- API Reference - Complete API documentation
- Batch API Guide - Batch processing guide
APK Download
- APK Download Implementation - Architecture and design
- Authentication: Get OAuth token from Google Embedded Setup
APK/DEX Analysis
- WebView Flow Analysis - Complete guide to WebView security analysis
- Rust Core API - Low-level API usage guide
🏗️ Architecture
Playfast uses pure Rust for maximum performance:
┌─────────────────────────────────────────────────────┐
│ Python High-level API │
│ - ApkDownloader (APK download) │
│ - ApkAnalyzer (APK/DEX analysis) │
│ - Batch API (Play Store scraping) │
│ - RustClient / AsyncClient │
│ - Pydantic Models │
└────────────────────┬────────────────────────────────┘
│ PyO3 Bindings
▼
┌─────────────────────────────────────────────────────┐
│ Rust Core (playfast.core) │
│ - Google Play API (gpapi - APK download) │
│ - HTTP Client (reqwest) │
│ - HTML Parser (scraper) │
│ - DEX Parser (custom) │
│ - Parallel Processing (rayon + tokio) │
│ - Complete GIL Release │
└─────────────────────────────────────────────────────┘
API Layers
| Layer | Components | Use Case |
|---|---|---|
| High-level | ApkDownloader, ApkAnalyzer, Batch API |
General users (90% of use cases) |
| Mid-level | RustClient, AsyncClient |
Direct scraping control |
| Low-level | playfast.core.* |
Security research, advanced analysis |
Client Options for Play Store Scraping
| Method | Speed | Ease | Best For |
|---|---|---|---|
| Batch API | ⚡⚡⚡ | ⭐⭐⭐ | Multiple items |
| RustClient | ⚡⚡⚡ | ⭐⭐ | Single items |
| AsyncClient | ⚡⚡ | ⭐⭐ | Async code |
🌍 Multi-Country Optimization
Playfast optimizes global data collection:
from playfast import get_unique_countries, get_representative_country
# Instead of 247 countries, use 93 unique stores (2.7x faster!)
unique = get_unique_countries() # 93 unique Play Stores
# Get representative for any country
rep = get_representative_country(
"fi"
) # Finland → Vanuatu store (shared by 138 countries)
🔧 Development
# Clone repository
git clone https://github.com/taeyun16/playfast.git
cd playfast
# Install dependencies
uv sync
# Build Rust extension
uv run maturin develop --release
# Run tests
uv run pytest
# Run examples
uv run python examples/basic.py
# Run benchmarks
uv run python benchmarks/batch_apps_benchmark.py
See Development Setup for detailed instructions.
🤝 Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request
📝 License
MIT License - see LICENSE for details.
🙏 Acknowledgments
- Built with PyO3 (Rust-Python bindings)
- Inspired by google-play-scraper
- APK Download: gpapi by EFF
- HTTP: reqwest
- Parsing: scraper
- Async Runtime: tokio
⚠️ Disclaimer
This tool is for educational and research purposes only. Please respect Google Play Store's Terms of Service. Use responsibly with appropriate rate limiting.
Made with ❤️ using Rust + Python
Metadata
Release files for playfast 0.5.10
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| playfast-0.5.10.tar.gz | 423.0 kB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| playfast-0.5.10-cp311-abi3-win_amd64.whl | CPython 3.11 | abi3 | Windows x86-64 | Details |
| playfast-0.5.10-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.11 | abi3 | Linux glibc 2.17+ x86-64 | Details |
| playfast-0.5.10-cp311-abi3-macosx_11_0_arm64.whl | CPython 3.11 | abi3 | macOS 11.0+ ARM64 | Details |
| playfast-0.5.10-cp311-abi3-macosx_10_12_x86_64.whl | CPython 3.11 | abi3 | macOS 10.12+ x86-64 | Details |
Total release size: 16.7 MB
Release files / playfast-0.5.10.tar.gz
| Download URL | playfast-0.5.10.tar.gz |
|---|---|
| Size | 423.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9bbb14e66b37f7a39c9cfb732e7d4df7f4d4f63a3fb5224a3375f8b4ad1015bb
|
|
BLAKE2b-256 checksum How to use checksums |
508c383fb51d29b869c0a848df960547a1fc95c3a2cc70beb8bdf1d28af02afa
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.13.1
|
Release files / playfast-0.5.10-cp311-abi3-win_amd64.whl
| Download URL | playfast-0.5.10-cp311-abi3-win_amd64.whl |
|---|---|
| Size | 3.7 MB |
| Tags | CPython 3.11 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
d846e0fa540459a7d625569dadc075af2ce3b658edb05cdd8d3b6dc77a3d22eb
|
|
BLAKE2b-256 checksum How to use checksums |
a041e24e8665e3663ba8585c849372a3dbbac1b0b9c8f26ee92d89d2f7ea2505
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.13.1
|
Release files / playfast-0.5.10-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | playfast-0.5.10-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 4.4 MB |
| Tags | CPython 3.11 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
f4300381af757f7d98f32468ec606f4d521acac04bd94ceb030ddb75d3294576
|
|
BLAKE2b-256 checksum How to use checksums |
ad0f1d54c241561b322cac80c5295905e23818f3f9fd14df81bae38fd35f4693
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.13.1
|
Release files / playfast-0.5.10-cp311-abi3-macosx_11_0_arm64.whl
| Download URL | playfast-0.5.10-cp311-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 4.0 MB |
| Tags | CPython 3.11 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
b168feee0930ad40f9cc529ef0b819f8cdd44edd83865ca66ad52d1b1e87899f
|
|
BLAKE2b-256 checksum How to use checksums |
98a234f560020fd785b2b2be3959cfdd7ed96edcbce24b37afdf89b4a8f37b6d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.13.1
|
Release files / playfast-0.5.10-cp311-abi3-macosx_10_12_x86_64.whl
| Download URL | playfast-0.5.10-cp311-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 4.2 MB |
| Tags | CPython 3.11 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
13f8039d3b2f1fdb864eefcffb5c91760b0bdfe3ea569d3b4afb1eee69d8b85f
|
|
BLAKE2b-256 checksum How to use checksums |
2d96352ede2d72080354c995455d6e904f892fd84801d9d130e0281fd61186ca
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.13.1
|