# appstore-connect-client
[](https://badge.fury.io/py/appstore-connect-client)
[](https://pypi.org/project/appstore-connect-client/)
[](LICENSE)
[](https://github.com/bickster/appstore-connect-python)
A comprehensive Python client for the Apple App Store Connect API, providing simple and intuitive interfaces for sales reporting, app metadata management, and advanced analytics.
## Features
- 📊 **Sales & Financial Reporting** - Daily, weekly, monthly sales and revenue data
- 🎯 **App Metadata Management** - Update app listings, descriptions, and keywords
- 📈 **Advanced Analytics** - Period comparisons, performance ranking, trend analysis
- 💳 **Subscription Analytics** - Active subscriptions, events, and lifecycle metrics
- 🌍 **Localization Support** - Multi-language content management
- 🚀 **Batch Operations** - Update multiple apps simultaneously
- 🔐 **Secure Authentication** - JWT ES256 token-based auth
- ⚡ **Smart Rate Limiting** - Automatic handling of API limits (50 requests/hour)
- 🐼 **Pandas Integration** - DataFrames for easy data manipulation
- ✅ **Type Hints** - Full type support for better IDE experience
## Installation
```bash
pip install appstore-connect-client
```
For development:
```bash
pip install appstore-connect-client[dev]
```
## Quick Start
```python
from appstore_connect import AppStoreConnectAPI
from datetime import date, timedelta
# Initialize the client
client = AppStoreConnectAPI(
key_id="your_key_id",
issuer_id="your_issuer_id",
private_key_path="/path/to/AuthKey_XXXXXX.p8",
vendor_number="your_vendor_number"
)
# Get yesterday's sales data
yesterday = date.today() - timedelta(days=1)
sales_df = client.get_sales_report(yesterday)
print(f"Revenue: ${sales_df['proceeds'].sum():,.2f}")
```
## Authentication
### Prerequisites
1. Apple Developer Account with App Store Connect access
2. App Store Connect API Key ([generate here](https://appstoreconnect.apple.com/access/api))
3. Private key file (.p8) downloaded from App Store Connect
4. Vendor number from your App Store Connect account
### Setting up credentials
You can provide credentials in three ways:
#### 1. Direct parameters (recommended)
```python
client = AppStoreConnectAPI(
key_id="your_key_id",
issuer_id="your_issuer_id",
private_key_path="/path/to/private_key.p8",
vendor_number="your_vendor_number"
)
```
#### 2. Environment variables
```bash
export APP_STORE_KEY_ID="your_key_id"
export APP_STORE_ISSUER_ID="your_issuer_id"
export APP_STORE_PRIVATE_KEY_PATH="/path/to/private_key.p8"
export APP_STORE_VENDOR_NUMBER="your_vendor_number"
```
```python
import os
client = AppStoreConnectAPI(
key_id=os.getenv('APP_STORE_KEY_ID'),
issuer_id=os.getenv('APP_STORE_ISSUER_ID'),
private_key_path=os.getenv('APP_STORE_PRIVATE_KEY_PATH'),
vendor_number=os.getenv('APP_STORE_VENDOR_NUMBER')
)
```
#### 3. Using .env file
Create a `.env` file based on `.env.example` and the client will load it automatically in development.
## Usage Examples
### Sales Reporting
```python
# Get comprehensive 30-day analytics
from appstore_connect import create_report_processor
processor = create_report_processor(
key_id=os.getenv('APP_STORE_KEY_ID'),
issuer_id=os.getenv('APP_STORE_ISSUER_ID'),
private_key_path=os.getenv('APP_STORE_PRIVATE_KEY_PATH'),
vendor_number=os.getenv('APP_STORE_VENDOR_NUMBER')
)
summary = processor.get_sales_summary(days=30)
print(f"Total Revenue: ${summary['summary']['total_revenue']:,.2f}")
print(f"Total Units: {summary['summary']['total_units']:,}")
# Compare performance periods
comparison = processor.compare_periods(current_days=30, comparison_days=30)
revenue_change = comparison['changes']['total_revenue']['change_percent']
print(f"Revenue Change: {revenue_change:+.1f}%")
```
### App Metadata Management
```python
from appstore_connect import create_metadata_manager
manager = create_metadata_manager(
key_id=os.getenv('APP_STORE_KEY_ID'),
issuer_id=os.getenv('APP_STORE_ISSUER_ID'),
private_key_path=os.getenv('APP_STORE_PRIVATE_KEY_PATH'),
vendor_number=os.getenv('APP_STORE_VENDOR_NUMBER')
)
# Update app listing
results = manager.update_app_listing(
app_id='123456789',
updates={
'name': 'My Awesome App',
'subtitle': 'The Best App Ever',
'description': 'This app will change your life...',
'keywords': 'productivity,utility,business'
}
)
# Batch update multiple apps
batch_updates = {
'123456789': {'subtitle': 'Productivity Booster'},
'987654321': {'subtitle': 'Entertainment Hub'}
}
results = manager.batch_update_apps(batch_updates)
```
### DataFrame Operations
```python
# Get sales data and calculate weekly totals
import pandas as pd
# Fetch multiple days efficiently
reports = client.fetch_multiple_days(days=90) # Automatically optimizes API calls
# Calculate weekly revenue
reports['week'] = pd.to_datetime(reports['begin_date']).dt.isocalendar().week
weekly_revenue = reports.groupby('week')['proceeds'].sum()
# Get top performing apps
top_apps = reports.groupby('app_name')['units'].sum().nlargest(10)
```
## API Reference
See [API Documentation](docs/API_REFERENCE.md) for complete reference.
### Core Components
- **AppStoreConnectAPI** - Main client for direct API access
- **ReportProcessor** - High-level analytics with advanced reporting
- **MetadataManager** - Portfolio management with batch operations
## Error Handling
```python
from appstore_connect.exceptions import (
AuthenticationError,
RateLimitError,
ValidationError,
PermissionError
)
try:
sales_df = client.get_sales_report(date.today())
except AuthenticationError:
print("Check your API credentials")
except RateLimitError:
print("Rate limit exceeded - wait before retrying")
except PermissionError:
print("Insufficient API key permissions")
except ValidationError as e:
print(f"Invalid input: {e}")
```
## Best Practices
1. **Reuse client instances** - Create once and reuse for multiple requests
2. **Use smart fetching** - Let the client optimize API calls for date ranges
3. **Handle rate limits** - Built-in retry logic, but be mindful of usage
4. **Leverage DataFrames** - Use pandas operations for data analysis
5. **Secure credentials** - Never commit credentials to version control
## Testing
```bash
# Run all tests
pytest
# Run with coverage
pytest --cov=appstore_connect --cov-report=term-missing
# Run specific test file
pytest tests/test_client.py
```
## Contributing
1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Install development dependencies: `pip install -e .[dev]`
4. Make your changes and add tests
5. Run tests: `python -m pytest`
6. Check formatting: `python -m black --check src/appstore_connect tests`
7. Format code: `python -m black src/appstore_connect tests`
8. Commit your changes (`git commit -m 'Add amazing feature'`)
9. Push to the branch (`git push origin feature/amazing-feature`)
10. Open a Pull Request
See [CLAUDE.md](CLAUDE.md) for detailed development commands.
## Documentation
- 📚 [Getting Started](docs/GETTING_STARTED.md) - Setup and basic usage
- 🔧 [API Reference](docs/API_REFERENCE.md) - Complete API documentation
- 🚑 [Troubleshooting](docs/TROUBLESHOOTING.md) - Common issues and solutions
- 💡 [Examples](examples/) - Comprehensive usage examples
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## Support
- 🐛 **Issues**: [GitHub Issues](https://github.com/bickster/appstore-connect-python/issues)
- 📖 **Documentation**: [Read the Docs](https://appstore-connect-client.readthedocs.io/)
- 💬 **Discussions**: [GitHub Discussions](https://github.com/bickster/appstore-connect-python/discussions)
## Changelog
See [CHANGELOG.md](CHANGELOG.md) for version history and changes.
---
**Made with ❤️ for iOS developers and app analytics teams**
Raw data
{
"_id": null,
"home_page": "https://github.com/bickster/appstore-connect-python",
"name": "apple-appstore-connect-client",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": null,
"keywords": "apple, app store connect, api, sales, metadata, ios, apps",
"author": "Chris Bick",
"author_email": "Chris Bick <chris@bickster.com>",
"download_url": "https://files.pythonhosted.org/packages/a7/d5/534fd730c18d5331dbff6ee55fd8c17855c6aff17d9da7efa4f597f7a63e/apple_appstore_connect_client-1.0.4.tar.gz",
"platform": null,
"description": "# appstore-connect-client\n\n[](https://badge.fury.io/py/appstore-connect-client)\n[](https://pypi.org/project/appstore-connect-client/)\n[](LICENSE)\n[](https://github.com/bickster/appstore-connect-python)\n\nA comprehensive Python client for the Apple App Store Connect API, providing simple and intuitive interfaces for sales reporting, app metadata management, and advanced analytics.\n\n## Features\n\n- \ud83d\udcca **Sales & Financial Reporting** - Daily, weekly, monthly sales and revenue data\n- \ud83c\udfaf **App Metadata Management** - Update app listings, descriptions, and keywords\n- \ud83d\udcc8 **Advanced Analytics** - Period comparisons, performance ranking, trend analysis\n- \ud83d\udcb3 **Subscription Analytics** - Active subscriptions, events, and lifecycle metrics\n- \ud83c\udf0d **Localization Support** - Multi-language content management\n- \ud83d\ude80 **Batch Operations** - Update multiple apps simultaneously\n- \ud83d\udd10 **Secure Authentication** - JWT ES256 token-based auth\n- \u26a1 **Smart Rate Limiting** - Automatic handling of API limits (50 requests/hour)\n- \ud83d\udc3c **Pandas Integration** - DataFrames for easy data manipulation\n- \u2705 **Type Hints** - Full type support for better IDE experience\n\n## Installation\n\n```bash\npip install appstore-connect-client\n```\n\nFor development:\n```bash\npip install appstore-connect-client[dev]\n```\n\n## Quick Start\n\n```python\nfrom appstore_connect import AppStoreConnectAPI\nfrom datetime import date, timedelta\n\n# Initialize the client\nclient = AppStoreConnectAPI(\n key_id=\"your_key_id\",\n issuer_id=\"your_issuer_id\",\n private_key_path=\"/path/to/AuthKey_XXXXXX.p8\",\n vendor_number=\"your_vendor_number\"\n)\n\n# Get yesterday's sales data\nyesterday = date.today() - timedelta(days=1)\nsales_df = client.get_sales_report(yesterday)\nprint(f\"Revenue: ${sales_df['proceeds'].sum():,.2f}\")\n```\n\n## Authentication\n\n### Prerequisites\n\n1. Apple Developer Account with App Store Connect access\n2. App Store Connect API Key ([generate here](https://appstoreconnect.apple.com/access/api))\n3. Private key file (.p8) downloaded from App Store Connect\n4. Vendor number from your App Store Connect account\n\n### Setting up credentials\n\nYou can provide credentials in three ways:\n\n#### 1. Direct parameters (recommended)\n```python\nclient = AppStoreConnectAPI(\n key_id=\"your_key_id\",\n issuer_id=\"your_issuer_id\",\n private_key_path=\"/path/to/private_key.p8\",\n vendor_number=\"your_vendor_number\"\n)\n```\n\n#### 2. Environment variables\n```bash\nexport APP_STORE_KEY_ID=\"your_key_id\"\nexport APP_STORE_ISSUER_ID=\"your_issuer_id\"\nexport APP_STORE_PRIVATE_KEY_PATH=\"/path/to/private_key.p8\"\nexport APP_STORE_VENDOR_NUMBER=\"your_vendor_number\"\n```\n\n```python\nimport os\nclient = AppStoreConnectAPI(\n key_id=os.getenv('APP_STORE_KEY_ID'),\n issuer_id=os.getenv('APP_STORE_ISSUER_ID'),\n private_key_path=os.getenv('APP_STORE_PRIVATE_KEY_PATH'),\n vendor_number=os.getenv('APP_STORE_VENDOR_NUMBER')\n)\n```\n\n#### 3. Using .env file\nCreate a `.env` file based on `.env.example` and the client will load it automatically in development.\n\n## Usage Examples\n\n### Sales Reporting\n```python\n# Get comprehensive 30-day analytics\nfrom appstore_connect import create_report_processor\n\nprocessor = create_report_processor(\n key_id=os.getenv('APP_STORE_KEY_ID'),\n issuer_id=os.getenv('APP_STORE_ISSUER_ID'),\n private_key_path=os.getenv('APP_STORE_PRIVATE_KEY_PATH'),\n vendor_number=os.getenv('APP_STORE_VENDOR_NUMBER')\n)\n\nsummary = processor.get_sales_summary(days=30)\nprint(f\"Total Revenue: ${summary['summary']['total_revenue']:,.2f}\")\nprint(f\"Total Units: {summary['summary']['total_units']:,}\")\n\n# Compare performance periods\ncomparison = processor.compare_periods(current_days=30, comparison_days=30)\nrevenue_change = comparison['changes']['total_revenue']['change_percent']\nprint(f\"Revenue Change: {revenue_change:+.1f}%\")\n```\n\n### App Metadata Management\n```python\nfrom appstore_connect import create_metadata_manager\n\nmanager = create_metadata_manager(\n key_id=os.getenv('APP_STORE_KEY_ID'),\n issuer_id=os.getenv('APP_STORE_ISSUER_ID'),\n private_key_path=os.getenv('APP_STORE_PRIVATE_KEY_PATH'),\n vendor_number=os.getenv('APP_STORE_VENDOR_NUMBER')\n)\n\n# Update app listing\nresults = manager.update_app_listing(\n app_id='123456789',\n updates={\n 'name': 'My Awesome App',\n 'subtitle': 'The Best App Ever',\n 'description': 'This app will change your life...',\n 'keywords': 'productivity,utility,business'\n }\n)\n\n# Batch update multiple apps\nbatch_updates = {\n '123456789': {'subtitle': 'Productivity Booster'},\n '987654321': {'subtitle': 'Entertainment Hub'}\n}\nresults = manager.batch_update_apps(batch_updates)\n```\n\n### DataFrame Operations\n```python\n# Get sales data and calculate weekly totals\nimport pandas as pd\n\n# Fetch multiple days efficiently\nreports = client.fetch_multiple_days(days=90) # Automatically optimizes API calls\n\n# Calculate weekly revenue\nreports['week'] = pd.to_datetime(reports['begin_date']).dt.isocalendar().week\nweekly_revenue = reports.groupby('week')['proceeds'].sum()\n\n# Get top performing apps\ntop_apps = reports.groupby('app_name')['units'].sum().nlargest(10)\n```\n\n## API Reference\n\nSee [API Documentation](docs/API_REFERENCE.md) for complete reference.\n\n### Core Components\n\n- **AppStoreConnectAPI** - Main client for direct API access\n- **ReportProcessor** - High-level analytics with advanced reporting\n- **MetadataManager** - Portfolio management with batch operations\n\n## Error Handling\n\n```python\nfrom appstore_connect.exceptions import (\n AuthenticationError,\n RateLimitError,\n ValidationError,\n PermissionError\n)\n\ntry:\n sales_df = client.get_sales_report(date.today())\nexcept AuthenticationError:\n print(\"Check your API credentials\")\nexcept RateLimitError:\n print(\"Rate limit exceeded - wait before retrying\")\nexcept PermissionError:\n print(\"Insufficient API key permissions\")\nexcept ValidationError as e:\n print(f\"Invalid input: {e}\")\n```\n\n## Best Practices\n\n1. **Reuse client instances** - Create once and reuse for multiple requests\n2. **Use smart fetching** - Let the client optimize API calls for date ranges\n3. **Handle rate limits** - Built-in retry logic, but be mindful of usage\n4. **Leverage DataFrames** - Use pandas operations for data analysis\n5. **Secure credentials** - Never commit credentials to version control\n\n## Testing\n\n```bash\n# Run all tests\npytest\n\n# Run with coverage\npytest --cov=appstore_connect --cov-report=term-missing\n\n# Run specific test file\npytest tests/test_client.py\n```\n\n## Contributing\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/amazing-feature`)\n3. Install development dependencies: `pip install -e .[dev]`\n4. Make your changes and add tests\n5. Run tests: `python -m pytest`\n6. Check formatting: `python -m black --check src/appstore_connect tests`\n7. Format code: `python -m black src/appstore_connect tests`\n8. Commit your changes (`git commit -m 'Add amazing feature'`)\n9. Push to the branch (`git push origin feature/amazing-feature`)\n10. Open a Pull Request\n\nSee [CLAUDE.md](CLAUDE.md) for detailed development commands.\n\n## Documentation\n\n- \ud83d\udcda [Getting Started](docs/GETTING_STARTED.md) - Setup and basic usage\n- \ud83d\udd27 [API Reference](docs/API_REFERENCE.md) - Complete API documentation\n- \ud83d\ude91 [Troubleshooting](docs/TROUBLESHOOTING.md) - Common issues and solutions\n- \ud83d\udca1 [Examples](examples/) - Comprehensive usage examples\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## Support\n\n- \ud83d\udc1b **Issues**: [GitHub Issues](https://github.com/bickster/appstore-connect-python/issues)\n- \ud83d\udcd6 **Documentation**: [Read the Docs](https://appstore-connect-client.readthedocs.io/)\n- \ud83d\udcac **Discussions**: [GitHub Discussions](https://github.com/bickster/appstore-connect-python/discussions)\n\n## Changelog\n\nSee [CHANGELOG.md](CHANGELOG.md) for version history and changes.\n\n---\n\n**Made with \u2764\ufe0f for iOS developers and app analytics teams**\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A comprehensive Python client for the Apple App Store Connect API",
"version": "1.0.4",
"project_urls": {
"Bug Tracker": "https://github.com/bickster/appstore-connect-python/issues",
"Documentation": "https://github.com/bickster/appstore-connect-python/blob/main/README.md",
"Homepage": "https://github.com/bickster/appstore-connect-python",
"Repository": "https://github.com/bickster/appstore-connect-python"
},
"split_keywords": [
"apple",
" app store connect",
" api",
" sales",
" metadata",
" ios",
" apps"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "39bb7ab57d6bf562084575cb697823fe7d32dd8c5e444be2a1e019f41ebc963c",
"md5": "8c5ce27b147daf96d3409654d370f330",
"sha256": "fa27c564ce45533de4c5d506901c0ee62203d1312ea908e73630c6e1721fc605"
},
"downloads": -1,
"filename": "apple_appstore_connect_client-1.0.4-py3-none-any.whl",
"has_sig": false,
"md5_digest": "8c5ce27b147daf96d3409654d370f330",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7",
"size": 5777,
"upload_time": "2025-07-17T02:08:12",
"upload_time_iso_8601": "2025-07-17T02:08:12.081405Z",
"url": "https://files.pythonhosted.org/packages/39/bb/7ab57d6bf562084575cb697823fe7d32dd8c5e444be2a1e019f41ebc963c/apple_appstore_connect_client-1.0.4-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "a7d5534fd730c18d5331dbff6ee55fd8c17855c6aff17d9da7efa4f597f7a63e",
"md5": "2da6aa83787d9b06f3be91dd3619e0f5",
"sha256": "2379449097070a217074a69d9144db023fce469cbce712d68610d74f077246a5"
},
"downloads": -1,
"filename": "apple_appstore_connect_client-1.0.4.tar.gz",
"has_sig": false,
"md5_digest": "2da6aa83787d9b06f3be91dd3619e0f5",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 77017,
"upload_time": "2025-07-17T02:08:13",
"upload_time_iso_8601": "2025-07-17T02:08:13.241530Z",
"url": "https://files.pythonhosted.org/packages/a7/d5/534fd730c18d5331dbff6ee55fd8c17855c6aff17d9da7efa4f597f7a63e/apple_appstore_connect_client-1.0.4.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-17 02:08:13",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "bickster",
"github_project": "appstore-connect-python",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "requests",
"specs": [
[
">=",
"2.31.0"
]
]
},
{
"name": "pandas",
"specs": [
[
">=",
"2.0.0"
]
]
},
{
"name": "PyJWT",
"specs": [
[
">=",
"2.8.0"
]
]
},
{
"name": "cryptography",
"specs": [
[
">=",
"41.0.0"
]
]
},
{
"name": "python-dateutil",
"specs": [
[
">=",
"2.8.0"
]
]
},
{
"name": "ratelimit",
"specs": [
[
">=",
"2.2.1"
]
]
}
],
"lcname": "apple-appstore-connect-client"
}