調用App Store Connect Api


對iOS的證書、描述文件、賬號、設備等管理,之前都去蘋果開發者中心操作,官網上操作也比較繁雜,想搞一些自動化之類的,更是麻煩,有時候官網都打不開……

其實蘋果還提供里一套API接口,創建證書、創建賬號、增加devices等等,這些都可以調用命令操作,可以按需來完成自動化操作或批量操作。

API接口地址:https://api.appstoreconnect.apple.com

文檔地址:https://developer.apple.com/documentation/appstoreconnectapi

有人可能看完文檔還是不知道怎么下手,簡述一下步驟:

1. 生成token

(1)key 和iss以及.p8文件生成就不累述

(2) 構造header

algorithm = 'ES256'
base_api_url = "https://api.appstoreconnect.apple.com"
header = {
        "alg": algorithm,
        "kid": key,
        "typ": "JWT"
    }

 

(3)構造payload

# 
    payload = {
        "iss": iss,
        "exp": int(time.mktime((datetime.now() + timedelta(minutes=20)).timetuple())),
        "aud": "appstoreconnect-v1"
    }

(4)生成token

token = jwt.encode(payload=payload, key=private_key, algorithm=algorithm, headers=header).decode('ascii')
    return token

(5)封裝請求處理

def base_call(url, token, method="get", data=None):
    """
    :param url:
    :param token:
    :param method:
    :param data:
    :return:
    """

    re_header = {"Authorization": "Bearer %s" % token}
    r = {}
    url = base_api_url + url

    requests.adapters.DEFAULT_RETRIES = 1
    req = requests.session()
    req.keep_alive = False

    if method.lower() == "get":
        r = req.get(url, params=data, headers=re_header)

    elif method.lower() == "post":
        re_header["Content-Type"] = "application/json"
        r = req.post(url=url, headers=re_header, data=json.dumps(data))

    elif method.lower() == "patch":
        re_header["Content-Type"] = "application/json"
        r = req.patch(url=url, headers=re_header, data=json.dumps(data))
    return r

 

比如我們以增加設備id為例:

 

 

def set_devices(api_token, data):
    """
    增加devices信息
    :param api_token:
    :param data:
    :return:
    """
    set_device_url = '/v1/devices'
    res = base_call(set_device_url, api_token, 'post', data)
    return res
post_data = {
    "data": {
        "attributes": {
        "name": i.split(',')[0],
        "platform": "IOS",
        "udid": i.split(',')[1]
          },
    "type": "devices"
    }
}
res = api.set_devices(api_token, post_data)
if res.status_code != 201:
    print(res.json()['errors'][0]['detail'])
else:
    print("add time:", res.json()['data']['attributes']['addedDate'])                

這里的參數組裝需要注意,需要參考文檔一層層組裝參數,data包含自子參數,子參數再包含子參數

 

完整的代碼示例:

# -*- coding:utf-8 -*-
# Author: drew
# create time: 2020-07030
# update time:
# app store connect api


import jwt
import time
import json
import requests
from datetime import datetime, timedelta


algorithm = 'ES256'
base_api_url = "https://api.appstoreconnect.apple.com"


def get_token(key, iss, key_file):
    """
    :param key:
    :param iss:
    :param key_file:
    :return:
    """
    # 讀取私鑰
    private_key = open(key_file, 'r').read()
    # 構造header
    header = {
        "alg": algorithm,
        "kid": key,
        "typ": "JWT"
    }
    # 構造payload
    payload = {
        "iss": iss,
        "exp": int(time.mktime((datetime.now() + timedelta(minutes=20)).timetuple())),
        "aud": "appstoreconnect-v1"
    }

    token = jwt.encode(payload=payload, key=private_key, algorithm=algorithm, headers=header).decode('ascii')
    return token


def base_call(url, token, method="get", data=None):
    """
    :param url:
    :param token:
    :param method:
    :param data:
    :return:
    """

    re_header = {"Authorization": "Bearer %s" % token}
    r = {}
    url = base_api_url + url

    requests.adapters.DEFAULT_RETRIES = 1
    req = requests.session()
    req.keep_alive = False

    if method.lower() == "get":
        r = req.get(url, params=data, headers=re_header)

    elif method.lower() == "post":
        re_header["Content-Type"] = "application/json"
        r = req.post(url=url, headers=re_header, data=json.dumps(data))

    elif method.lower() == "patch":
        re_header["Content-Type"] = "application/json"
        r = req.patch(url=url, headers=re_header, data=json.dumps(data))
    return r

# ------------------ 獲取具體接口的方法 ------------------


def get_devices(api_token, data=None):
    """
    獲取devices信息
    :param api_token:
    :param data:
    :return:
    """
    get_devices_url = '/v1/devices'
    if data is None:
        data = {
            "filter[platform]": "IOS",
            # "filter[status]": "ENABLED",
            "limit": 100
        }
    res = base_call(get_devices_url, api_token, 'get', data)
    return res


def set_devices(api_token, data):
    """
    增加devices信息
    :param api_token:
    :param data:
    :return:
    """
    set_device_url = '/v1/devices'
    res = base_call(set_device_url, api_token, 'post', data)
    return res


def update_devices(api_token, id, data,):
    """
    增加devices信息
    :param id:
    :param api_token:
    :param data:
    :return:
    """
    set_device_url = '/v1/devices/{%s}' % id
    res = base_call(set_device_url, api_token, 'patch', data)
    return res



"""
if __name__ == "__main__":

    ios_api_key = 'T8****8AD8'
    ios_api_issuer = '69a**9-b79b-4**3-e053-5b**1a4d1'
    file_key = "/Users/drew/.private_keys/AuthKey_T85LR***8.p8"
    token_api = get_token(ios_api_key, ios_api_issuer, file_key)
    # get_udid()
    post_data = {
        "data": {
            "attributes": {
                "name": "zb",
                "platform": "IOS",
                "udid": "80b677c2c****e476caf61ba0d34274000"
            },
            "type": "devices"
        }
    }

    res = set_udid(token_api, post_data)
    print(res)
"""

 

 

 
 
        



 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM