Metadata-Version: 2.4
Name: appstore-cli
Version: 0.1.1
Summary: App Store Connect from the command line. Install with `pip install appstore-cli`, then run `appstore`.
Author: Tarun Kundra
License-Expression: MIT
Project-URL: Homepage, https://github.com/ohmguru/AppStoreConnectCLI
Project-URL: Issues, https://github.com/ohmguru/AppStoreConnectCLI/issues
Keywords: apple,app-store-connect,cli,testflight,ios
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Build Tools
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: click
Requires-Dist: pyjwt[crypto]
Requires-Dist: requests
Requires-Dist: python-dotenv

# appstore-cli

A command-line interface for the [App Store Connect API](https://developer.apple.com/documentation/appstoreconnectapi). Manage apps, builds, TestFlight, certificates, provisioning profiles, App Store submissions, and 190+ other resources — all from your terminal.

Commands are auto-generated from Apple's OpenAPI spec via a compact manifest, so when Apple ships new API endpoints, a single `python3 generate_manifest.py` brings them into the CLI.

## Quick start

```bash
pip install appstore-cli
appstore auth setup          # walks you through Key ID, Issuer ID, .p8 path
appstore apps list           # verify it works
```

## Requirements

- Python 3.9+
- An [App Store Connect API key](https://appstoreconnect.apple.com/access/integrations/api) (`.p8` file)

## Installation

**From PyPI (recommended):**

```bash
pip install appstore-cli
```

Or with [pipx](https://pipx.pypa.io/) for an isolated install:

```bash
pipx install appstore-cli
```

**With Homebrew:**

```bash
brew tap ohmguru/tap
brew install appstore-cli
```

**From source:**

```bash
git clone https://github.com/ohmguru/AppStoreConnectCLI.git
cd AppStoreConnectCLI
pip install .
```

## Authentication

`appstore` needs three values to authenticate: **Key ID**, **Issuer ID**, and the path to your **`.p8` private key**.

**Interactive setup (recommended):**

```bash
appstore auth setup
```

Prompts for each value and saves them to `~/.config/appstore/default.env` (chmod 600).

**Environment variables** (override any profile):

```bash
export ASC_KEY_ID=...
export ASC_ISSUER_ID=...
export ASC_KEY_PATH=...
```

### Multiple profiles

If you work across multiple teams or accounts, create named profiles:

```bash
appstore auth setup                  # default profile
appstore auth setup --profile work   # additional profile
appstore auth setup --profile client # another one

appstore auth list                   # show all profiles
appstore auth use work               # switch active profile
appstore auth status                 # show active profile details
appstore auth reset --profile client # remove a profile
```

Use `--profile` on any command for a one-off override without switching:

```bash
appstore --profile work apps list
```

Profiles are stored as individual files in `~/.config/appstore/`:

```
~/.config/appstore/
  active          # contains name of active profile
  default.env     # default profile credentials
  work.env        # work profile credentials
```

## Usage

```
appstore [--json] [--profile NAME] <resource> <command> [options]
```

### Apps & Builds

```bash
appstore apps list
appstore apps list --filter-bundle-id com.example.MyApp
appstore apps get APP_ID

appstore builds list --include app --sort -uploadedDate
appstore builds list --filter-app APP_ID --include app
appstore builds get BUILD_ID
```

### Certificates, Profiles & Devices

```bash
appstore certificates list --filter-certificate-type IOS_DISTRIBUTION --sort displayName
appstore certificates create --csr-content "$(cat req.csr)" --certificate-type IOS_DISTRIBUTION
appstore certificates delete CERT_ID

appstore profiles list --filter-profile-type IOS_APP_STORE
appstore devices list --filter-platform IOS
appstore devices create --name "iPhone" --platform IOS --udid UDID_HERE

appstore bundle-ids list --filter-platform IOS
appstore bundle-ids create --name "MyApp" --platform IOS --identifier com.example.MyApp
```

### TestFlight

```bash
appstore beta-groups list --include app
appstore beta-groups create --name "Testers" --app-id APP_ID
appstore beta-groups add-build GROUP_ID BUILD_ID
appstore beta-groups remove-build GROUP_ID BUILD_ID

appstore beta-testers list --filter-email user@example.com
appstore beta-testers create --email user@example.com --first-name Jane --last-name Doe \
    --beta-groups-id GROUP_ID

appstore beta-app-review-submissions create --build-id BUILD_ID
```

### App Store Submissions

```bash
appstore app-store-versions create --version-string 1.2.0 --platform IOS --app-id APP_ID
appstore app-store-versions set-build VERSION_ID BUILD_ID

appstore review-submissions create --platform IOS --app-id APP_ID
appstore review-submissions get SUBMISSION_ID
```

### More resources

There are 198 resource groups in total. Run `appstore --help` to see them all, or `appstore <resource> --help` for available subcommands.

```bash
appstore users list
appstore in-app-purchases list
appstore subscriptions get SUB_ID
appstore customer-reviews list
```

### Common options

Every `list` command supports:

| Option | Description |
|---|---|
| `--limit N` | Max results per page (default 200) |
| `--all` | Auto-paginate through all results |
| `--sort FIELD` | Sort by field (prefix with `-` for descending) |
| `--filter-FIELD VALUE` | Filter results (available filters vary by resource) |
| `--include TYPE` | Sideload related resources into the response |

Add `--json` before any subcommand for raw JSON:API output:

```bash
appstore --json builds list --limit 5
```

Use `--help` on any command to see all available options:

```bash
appstore certificates list --help
```

## How it works

```
openapi.oas.json  ──▶  generate_manifest.py  ──▶  manifest.json  ──▶  appstore (generic engine)
   (Apple spec)            (one-time gen)          (198 resources)       (CLI commands)
```

1. **`generate_manifest.py`** parses Apple's OpenAPI spec and extracts a compact manifest of every resource: paths, operations, filters, sort fields, create/update schemas, and display attributes.
2. **`manifest.json`** is the generated output — bundled inside the `appstore_cli` package so the CLI works without the 6 MB OpenAPI spec at runtime.
3. **`appstore`** loads the manifest at startup and dynamically registers Click command groups for each resource. The only hand-written command is `auth` (credential management).

### Updating when Apple releases a new API version

1. Download the latest [OpenAPI spec](https://developer.apple.com/sample-code/app-store-connect/app-store-connect-openapi-specification.zip)
2. Place `openapi.oas.json` in the project root
3. Regenerate:

```bash
python3 generate_manifest.py
```

4. Commit the updated `appstore_cli/manifest.json`

### Customizing commands

To override any generic command with a hand-written one, add a Click group with the same name in `cli.py` before `register_generic_commands()` is called. The engine skips any name that's already registered.

## Project structure

```
appstore_cli/
  __init__.py           Package init
  cli.py                CLI entry point
  manifest.json         Generated resource definitions (198 resources)
generate_manifest.py    OpenAPI → manifest generator
pyproject.toml          Package metadata and dependencies
```

## License

MIT
